画像のコストを下げるために、背景画像に tileMode=”repeat” を指定してタイルとして使っていたのですが、
Android 2.3 系以下の端末で特定のアクティビティでだけリピートが聞かなくてハマりました。
どうやらハニカムで修正されたOSの不具合だそうで…以下対策がわかったのでメモ。
どういう状況?
タイル背景(bg.xml)はこんな感じです。
<!-- res/drawable/bg.xml -->
< ?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:antialias="true"
android:dither="false"
android:filter="false"
android:gravity="fill"
android:src="@drawable/bg_repeat"
android:tileMode="repeat"></bitmap>
これを各レイアウトで次のように使っています。
< ?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg" >
リピートが効く画面もあるのですが、効かない画面では伸びたタイル画像が
1枚だけ表示されてしまいます。これはかっこ悪い。
直し方は?
StackOverFlow(background image not repeating in android layout)に書かれていました。
下のコードを適宜、描画の更新タイミングでリピートを行なっているビューに対して実行するといいようです。
public static void fixBackgroundRepeat(View view) {
Drawable bg = view.getBackground();
if(bg != null) {
if(bg instanceof BitmapDrawable) {
BitmapDrawable bmp = (BitmapDrawable) bg;
bmp.mutate(); // make sure that we aren't sharing state anymore
bmp.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
}
}
}
画面背景のリピートを修正するならこのように実行すればいいでしょう。
fixBackgroundRepeat(this.findViewById(android.R.id.content) .getRootView());
どうしてこうなった
StackOverFlowのコメントによると、ハニカム(Android 3.0)で修正された不具合のようで、同じ画面でBitmapDrawableが多数使われていると、内部でのBitmap(とBitmapの状態設定)の再利用のタイミングでtileMode設定が簡単に失われてしまうようです。
対策で行っていることは、消えてしまった背景画像のリピート設定を再度設定し直しているのですね。