2012年8月10日金曜日

カラー状態リストリソースと、状態Drawableは組み合わせられない

デフォルトのボタンを避けたい時、画像を用意できればいいんだけど、イラストレーターやらPhotoshopを使いこなせる人がいないって時は、さくっとShape Drawableで作るのが常套手段。

「CSS3で実装されたボタン」系のサイトをカラーカタログにするといい感じのボタンが簡単に作れます。

押しても反応がないのはボタンとしては致命的欠陥なので、押されている、有効無効、フォーカスが当たっている、など必要な状態に応じて何パターンか作る必要があります。

しかしボタンの形状はどれも同じなので、色の指定だけが違う大量のxmlを作ることになります。コピペをするとDRY神の教えに反するようでとてもバツが悪い気分です。

----

状態に合わせて異なる色を示すリソースがあれば良い様に思います。

まさにそういう目的で作られているのが、カラー状態リストリソース(Color State List)です。

ボタン画像を作ったら、直接Buttonのbackgroundに指定するのではなくて、stylesリソースを経由すると思うのですが(していないのであれば、ぜひしましょう)、ボタンが無効になっているときは画像だけでなく文字も暗くなっていた方がいいですし、ハイライト時に色が変わるとより映えます。

stylesリソースで、生成したボタン画像を背景に設定する際は、一緒にカラー状態リストで文字色を指定すると、そうした状態による色の違いを簡単に表現できます。

これでボタンの色も変えられるならば、ボタンの形状を示すShapeDrawableのxml1種類と、StateDrawableのxml、そしてカラー状態リストのxmlを必要数用意すればよくなります。

----

しかし、残念ながらその組み合わせはできません。

カラー状態リストとはStateColorListインスタンスを作るための設計書に過ぎないのです。そのStateColorListは実行時に状態に応じて色を返すだけのオブジェクトであり、色として指定できる色リテラルそのものではないのです。

同様に、StateDrawableもStateListDrawableのインスタンスを生成するための設計書に過ぎませんから、xmlからボタンをinflateするその瞬間は、「状態が存在しない状態」なので、機械的にカラー状態リストの先頭の色が選ばれます。

内部構造も見てみると、StateListDrawableのパーサは、個々のDrawableを生成するためにDrawableのパーサを利用しています。Drawableのパーサに引き渡された時点で、「状態」の情報は失われているわけですね。

0 件のコメント:

コメントを投稿