2014年6月12日木曜日

【Android】画像をぴったり繰り返すアイデア

前回のエントリではBitmapDrawableのsetTileModeXYメソッドを使って
画像の繰り返し配置を実現したけど
それだけじゃ一番端が切れてしまう.
前回のRepetitiveImageViewに分かりやすいように

この画像を適用させて表示した結果が以下のとおりである.


一番右端の子が途中で切れてしまっている.
特に問題ないことが多いと思うが,
どうしてもキッチリ収まってないと気になってしまう人へ

こんなアイデア.
タイル画像のサイズとView自体のサイズを取得し
繰り返す回数を計算する(Viewサイズ÷タイル画像サイズ)
余白(Viewサイズ%タイル画像サイズ)を繰り返す回数で割って
余白分だけ大きくなるようにタイル画像を少し拡大する

例を出すと
Viewの幅が100で
画像の幅が30だと仮定する.
まず繰り返す回数を計算する
100÷30 = 3
余白は100 % 30 = 10
この10を繰り返す3枚分に分け与えて
画像サイズを33.3333…にする.
そうすれば3回繰り返すと99.9999…となって
余白なく繰り返すことができる.

ん?33.3333…?
画像サイズが33.3333…?

ここで破綻する.
画像サイズはint値なので.33333なんてものは認められない.
また,TileModeの設定上全て同じサイズになるので
1枚だけ34で残り2枚を33なんて器用な真似はできない.

小数無視すればいいじゃんと考えるかもしれないが
計算しやすいように100と30という値を選んだが,
繰り返し回数が10回とかいう実際の環境だと
丸めた小数はバカに出来ないくらい大きくなり
数ピクセルの誤差が出てしまう.

じゃあ別の方法を採るしかない.
というわけで別案.
いわゆるゴリ押し.

NewRepetitiveImageViewというクラスを作ったが,
ImageViewはもはや関係もないLinearLayoutのサブクラス.

考え方としては上記のモノを引き継ぐのだが
タイル画像のサイズとView自体のサイズを取得し
繰り返す回数を計算する(Viewサイズ÷タイル画像サイズ)
ここまで一緒
繰り返し回数分LinearLayoutに子Viewを追加して
そのViewの背景画像としてタイル画像を設定
LinearLayoutには子Viewのサイズを等分割するモードがあるので
あとはLinearLayoutまかせ
という方法.

ソースコード例としてはこんな感じになる.

凄まじく御丁寧にコメントを書いたので内容はそっち読んでね.
GlaphicalLayoutが役に立たないよ.

使い方はレイアウトXMLに配置して
android:backgroundに繰り返したい画像をセットするだけ.
で,実機での動作が以下のとおり.

上が今回のNewRepetitiveImageViewで
下が前回のRepetitiveImageView.
今回のViewは枠にぴったり収まってるのがわかるね.


これダイアログの枠とかで実用的だと思うんだ.
9patchだと繰り返しができないからね.

今回は横に並べたけど
縦に並べることもできる.
OrientationをVerticalにして
widthとheightでやってることを入れ替える.

縦横配置は…
やめたほうがいい.

前回できたMirrorタイル配置はこのままではできないけど
ソースコードでBitmap展開して反転してってやるより
画像のほうで対応したほうが楽だよ.

0 件のコメント:

コメントを投稿