2011年4月1日金曜日

Android 状態によって色を変える

ListViewでは複数のリストを表示できないので、複数リストを表示する方法を考えていた。前回で区切り線まで引いた。後はフォーカス時の色を変えれたらそれなりにリストっぽくなるだろう。

と、言うことでフォーカス時に背景色、テキスト色を変える方法を調べたのでまとめる。

ColorStateListを使えば状態による色を定義することができる。
状態には、
  • android:state_pressed
  • android:state_focused
  • android:state_selected
  • android:state_checkable
  • android:state_checked
  • android:state_enabled
  • android:state_window_focused
がある。

定義リストをxmlで記述するのに注意しといた方が良いのは、このあたりか。
During each state change, the state list is traversed top to bottom and the first item that matches the current state will be used—the selection is not based on the "best match," but simply the first item that meets the minimum criteria of the state.
定義リストを頭から見ていって初めにマッチしたものが使われる。ベストマッチしたものじゃないよってこと。例えば、下記の順で書くと、focusedかつpressedの状態でも一個目にマッチするので、使われるのは一つ目。順番を逆に書けば良いだけ。
android:state_focused=true
android:state_focused=true android:state_pressed=true

ここまでがColorStateListの簡単な説明。


ここからは、前回のリストをフォーカスされたら色を変えるように修正していく。
まずはColorStateListリソースを用意する。

・color/row_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:drawable="@color/orange" />
    <item android:drawable="@color/black" />
</selector>
・color/row_text.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:color="@color/black" />
    <item android:color="@color/grey" />
</selector>
背景色はdrawableで文字色はcolorとする。itemのattributesにandroid:drawableが書かれていなかったので少しハマった。black、orange、greyについてはcolors.xmlに定義してあるが、colors.xmlは省略。

あとはリストの要素だったrow.xmlに属性を追加して下記のようにする。文字色と背景色の指定と、focusできるようにandroid:focusable="true"を追加。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:padding="10dip" android:textColor="@color/row_text"
    android:background="@color/row_bg" android:focusable="true" />

これで完成!!