StateListDrawable and tiled bitmap
Asked Answered
S

1

8

This is my custom selector (StateListDrawable)

<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/common_cell_background" />
    <item
        android:state_pressed="true"
        android:drawable="@drawable/common_cell_background_highlight" />
    <item
        android:state_focused="true"
        android:drawable="@drawable/common_cell_background_highlight" />
    <item
        android:state_selected="true"
        android:drawable="@drawable/common_cell_background_highlight" />
</selector>

Both, common_cell_background and common_cell_background_highlight are XML. Code below:

common_cell_background.xml

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/common_cell_background_bitmap"
    android:tileMode="repeat"
    android:dither="true">
</bitmap>

common_cell_background_highlight.xml

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/common_cell_background_bitmap_highlight"
    android:tileMode="repeat"
    android:dither="true">
</bitmap>

Bitmaps are also exactly the same. Highlight is just a little bit lighter and there is no other differences. Both bitmaps are PNG files.

Now I set

convertView.setBackgroundResource(R.drawable.list_item_background);

and here is the problem. My common_cell_background doesn't repeat, it's stretched. But what is suprising when I touch on cell of my list background changes to common_cell_background_highlight and guess what? Everything is fine, it's repeated like it should be. I have no idea where is the problem, why my background doesn't repeat while highlight does. Any thoughts?

Shawn answered 14/9, 2011 at 6:59 Comment(4)
same problem here. Seems like it's random: sometimes the bitmap gets repeated properly, sometimes it's stretchedPublicspirited
same problem here. driving me nuts. please post a solution if you do find one. thank u!Sunderland
see this: https://mcmap.net/q/339466/-xml-drawable-bitmap-tilemode-bugTai
@Tai Please post your comment as answer, I'll mark it as correct.Shawn
T
3

This is the bug, it was fixed in ICS, see this answer: https://mcmap.net/q/339466/-xml-drawable-bitmap-tilemode-bug

Here is a workaround: https://mcmap.net/q/334273/-tiled-drawable-sometimes-stretches

Note, that the workaround is only applicable for BitmapDrawable, for other types of drawables like StateListDrawable you'll need to do extra work. Here is what I use:

public static void fixBackgrndTileMode(View view, TileMode tileModeX, TileMode tileModeY) {
    if (view != null) {
        Drawable bg = view.getBackground();

        if (bg instanceof BitmapDrawable) {
            BitmapDrawable bmp = (BitmapDrawable) bg;
            bmp.mutate(); // make sure that we aren't sharing state anymore
            bmp.setTileModeXY(tileModeX, tileModeY);
        }
        else if (bg instanceof StateListDrawable) {
            StateListDrawable stateDrwbl = (StateListDrawable) bg;
            stateDrwbl.mutate(); // make sure that we aren't sharing state anymore

            ConstantState constantState = stateDrwbl.getConstantState();
            if (constantState instanceof DrawableContainerState) {
                DrawableContainerState drwblContainerState = (DrawableContainerState)constantState;
                final Drawable[] drawables = drwblContainerState.getChildren();
                for (Drawable drwbl : drawables) {
                    if (drwbl instanceof BitmapDrawable)
                        ((BitmapDrawable)drwbl).setTileModeXY(tileModeX, tileModeY);
                }
            }
        }
    }
}
Tai answered 22/6, 2012 at 9:8 Comment(1)
How do you apply it to a Drawable defined in xml?Antique

© 2022 - 2024 — McMap. All rights reserved.