#ご挨拶 今日も無銭知的労働に勤しむ大学生です。ご機嫌よう。
徳島の街は21時には主な飲食店が閉まったりするので悲しいね! でも大学周辺にいい感じの飲食店少ないんだぜ!ひっどい!
#本題:ImageViewで画像やDrawableをレイヤー表示する。 昨日の記事 でのサンプルXML、不思議でしたね。 完成図では4つの画像なのにImageViewが8つあったりね。
実は昨日本当にやりたかったことは、
- タップした画像が
- 「今これ選択されてますよー!」というのを
- ユーザーにわかりやすく示して
- でも細かいデザインにもこだわりたい・・・!
という欲求を解決したかったのです。ありがちですね。 そんなわけで、先に仕上がり図を見せます。 http://twitpic.com/9qkrug
注目してみていただきたいところとして、
- 丸とバツの画像
- フォーカスがあることを示すShape
- 対象となる画像
の順にかさなっています。この順番が重要で、例えば対象となる画像がShapeより上にくると見苦しいものになるんですね。 えっそんな細かいところ誰も気にしない?はい。
ともかく、この重なりをどうやって実現するか、ですが、 2つの重要ポイントを抑えるだけです。
- FrameLayoutでImageView2つを重ねる
- ImageView 1つにつき、2つのDrawableが設定できる
FrameLayoutでViewを重ねる
実はこれはAndroid Developersに掲載 されています。 リンク先のxmlをご覧ください。非常にシンプルです。 FrameLayout内にImageViewを2つ置くだけで、まず画像2つの重ね合わせを実現することができます。 個人的に思ったのが、FrameLayoutは大皿で、その上にピザとか食パンとか積み重ねていくイメージです。
ImageViewには2つのDrawableが設定できる
FrameLayoutで重ねあわせていくなら、あとは必要枚数だけImageViewを置いて、といきたいですが、 そうなるとIDは、ImageViewをおいた数だけ増えるという事です。 これは結構煩雑で、その都度findViewById呼ぶのかよ、という話です。(※)
で、今回は3つのDrawableを重ねるわけですが、ImageViewは、
- setImageDrawable
- setBackgroudDrawable
のメソッドを呼び出せます。俺が言う「ImageView1つにつき2つのDrawableが設定できる」の根拠です。 今回、2階層目はShapeなので、これをBackgroundに持ってきて、一番上の丸とバツはImageとしてセットしています。
これで、見かけ上3レイヤーあるようなUIが完成すると思います。
考察
レイヤーを作る、と考えた時、LayerDrawableを使う方法 もあるのですが、 俺の今回の要求はLayerDrawableでは実現できませんでした。
というのも、LayerDrawableをShapeと○×画像に直接使うと、Shapeのサイズが○×画像と同じになり、 その後ImageViewに表示すると、非常に残念なことになってしまいました。 原因は推測ですが、仮想キャンパス(というものが仮にあるとして、)の最大サイズが、予め画像サイズがわかっている○×画像のサイズにセットされたのではないかな、と思っております。
そんなわけで、Shapeのサイズを固定させるためにImageViewに貼り付け・・・、あっ、ImageViewのImageDrawableはまだ未使用なんだね!と気が付きました。
余談
唐揚げ弁当食べたいな。
(※)
最近、こういうコードを書いてオブジェクトの操作をやってますが、これは割と一般的な操作方法なんでしょうか。。。
private FrameLayout[] frameLayouts = new FrameLayout[4];
private int[] QuizSelectId = {
R.id.clickable_select_one,
R.id.clickable_select_two,
R.id.clickable_select_three,
R.id.clickable_select_four
};
(中略)
for (int i = 0; i < 4; i++) {
frameLayouts[i] = (FrameLayout) getActivity().findViewById(QuizSelectId[i]);
}
OSO2012では、onClickListenerをセットする程度ならfindViewByIdに直接書くという有難い助言も頂いてたりします。 こんな感じですね。
findViewById(R.id.button_ok).setOnClickListener(new OnClickListener(){ /* コード */ });
でもTextViewで文字操作したりすると、これだけでは限界があったりするというのも知っておくべきこと、というか最近知りました。