ColorStateListの注意点
ColorStateListについて
まず、ColorStateList
に簡単に説明です。
res/color
にxmlファイルとして定義することが出来ます。
これをButtonの android:textColor
に設定することで、押したときにテキストの色を変更できます。
また、すこし別の使い方として、既存の色に android:alpha
の値を設定して新たに色の定義として使用することができます。
似たようなものに StateListDrawable
があります。こちらはColorではなくDrawableになります。
この ColorStateList
を使ったときの注意について解説していきます。
コードから設定するとき (Android 5.x以下)
レイアウトXMLで設定するときには基本的に問題はならないですが、コードから設定するとき、且つ Android 5.x以下 の場合に注意が必要です。
例えば、以下のようにThemeのattributeを使って色を指定しているときです。 ?attr/colorPrimary
の箇所ですね。これは半透明にしてます。
このとき、 ContextCompat.getColorStateList
で取得して設定すると Android 5.x 以下の場合はThemeが反映されません。なので、期待している色を取得できません。
ドキュメントにも記載されていますが、23以降しかThemeが反映されません。
Starting in Build.VERSION_CODES.M, the returned color state list will be styled for the specified Context’s theme.
これを解決するには、AppCompatResources.getColorStateList
を使います。これを使うとThemeが反映された状態で色を取得するので、期待する色が取得できます。
Android 5.xのサポートは減ってきてるかもですが、使用する際は気をつけてください。
Backgroundに設定する場合
これはどのAndroidバージョンでも注意が必要です。
同じく半透明にする ColorStateList
を使います。
これを通常のcolorリソースと同じようにViewの android:background
に設定します。
これはコンパイルエラーが起きることなく実行することができ、更にやっかいなことにバージョンによって挙動が異なります。
- Android 10以降 => 動く(でも、問題あり)
- Android 10未満 => クラッシュする
Android 10未満の場合はクラッシュするので、すぐ気づくことができますが、10以降の場合は半端に動くので微妙に気づきにくいです。
Android 10以降の場合は動いてるように見えるのですが、同じ ColorStateList
を使用しているViewが複数あると、2つ目以降に色が設定されません。
これを解決するには Drawable リソースをちゃんと作る必要があります。res/drawable
に作成して、これをBackgoundに設定すれば、問題なく動きます。
このあたり気づきにくい部分だったりするので、注意しましょう。