2014年6月11日水曜日

【Android】画像を繰り返すImageView

先に言っておくけど別にImageViewじゃなくてもいいんだからね.

さて,ImageViewってのは指定した画像を1回だけ表示するものなんだよ.
ImageView::scaleTypeの指定によって
ImageView自体の大きさに画像をどうフィットさせるか/させないかを
指定させることはできても
Viewの中に表示される画像は1回だけなのね.
タイル配置みたいな繰り返し表示はできない.

9patchなんてものを大きく打ち出してカバーしてる一方で
androidってタイル配置に関してはそのままでは実現できない.

9patchは確かに便利なんだけど
時と場合によるよね.
繰り返しパターンには向いていない.

そこでタイル配置を実現するために
/res/drawable配下にXMLを作って
<bitmap>を作ろうっていうのがたくさん散見されるので
その場合はそちらを参考に.
新しく書く必要もない.

かといってこのエントリも新しく書く必要があるのかどうかと問われると微妙なんだけどね.

やっぱりレイアウトXMLにViewを配置して
画像リソースを指定したらタイル配置画像が表示される
っていうのがやりたいやん?
タイル画像がたくさんある場合に画像の数だけXMLがdrawable下に増えてくるのも鬱陶しいやん?
という個人的なワガママを個人的に解決.スッキリ

ImageViewを継承したRepetitiveImageViewなんていうものを作ってみた.
といっても大したことをしていないので見てほしい.


ソースの半分を占めるコンストラクタなんだけど
自作Viewを作るときはいつもこの3つをちゃんと宣言するようにしている.
引数1のコンストラクタがないとソースコードで扱う場合に面倒だし

楽:CustomView customview = new CustomView (this);
嫌:CustomView customview = new CustomView (this, null, 0);
毎回こんなの書くの嫌だよ.

引数2のコンストラクタがないとレイアウトXMLに配置したときに
GraphicalLayoutがエラーを返す.
引数3のコンストラクタは自分では基本使わないけど
何かの時に何気にやくにたつかもしれない
ということで毎回全部実装しているよ.
といっても今回は親クラス(ImageView)のコンストラクタに丸投げするだけで
なにもしていないけどね.

setImageDrawableは親クラス(ImageView)のオーバーライド.
でも親クラスのsetImageDrawableは呼び出していないよ.
見ての通りImageViewの前景画像として飛んできたDrawableを前景画像として使わずに
奪って背景画像として使っているよ.
その際にDrawableを一旦(Drawableのサブクラスである)BitmapDrawableにキャストして
BitmapDrawableのsetTileModeXYというメソッドを使ってタイル配置を実現している.

背景画像として表示しているため
最初に言ったとおり別にImageViewでなくてもViewであればなんでもいいんだよね.
FrameLayoutとかのViewGroup系でもいい.
タイルで嬉しいのは
ボーダーか背景かだと思うので
背景として使う場合はViewGroup系がいいんだろうね.
その場合はこのコードでやってることを
setBackgroundDrawableとかでやるといいんじゃない(適当)

で,使い方は
レイアウトXMLに

こんなかんじで使ってやればOK.
画像はこの画像を使ったよ.

そしてこの結果は以下のとおりになるよ.

もし↓のように書き換えると

こうなる.


両方ともmatch_parentにすると

こうなる.

圧巻

それだけで終わるのもなんなので,
setImageDrawableで指定している
d.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);

d.setTileModeXY(TileMode.MIRROR, TileMode.MIRROR);
こうすると

反転タイルになる.



TileModeにはもうひとつ,
TileMode.CLAMPなんていうものがある.
このモードがわかりやすいように使う画像を

これに変更.
CLAMPモードは画像端が引き伸ばされる.

(これやったら9patchでええやん)

0 件のコメント:

コメントを投稿