Tiled drawable sometimes stretches
Asked Answered
V

8

55

I have a ListView whose items have a tiled background. To accomplish this, I use the following drawable xml:

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

Usually, this works. Sometimes, however, the src drawable isn't tiled, but stretched to fill the entire list item. (I've got several different tiles like this, and I use them mixed in one ListView. If there is stretching instead of tiling, it's never been in all of them at once, for what that's worth.)

I also tried to add android:dither="true" to that xml, since I read somewhere that without it there might be bugs. That didn't change anything.

Has anyone had the same problem? How did you fix it?

Viceregent answered 2/12, 2010 at 14:54 Comment(7)
I'm experiencing the same issue. Any resolution yet?Incarnation
Can you post the view assembly code starting with the adapter's getView? I have a hunch the tilemode is getting reset when using a recycled view.Inimical
I can confirm this behavior too. In my case- it seems totally radom. Tiled background drawable sometimes is just not tiled. Instead stretched to whole area or also only horizontally tiled vertically. I haven't find solution yet. But I put it out here- so if somebody has exact problem can relate :)Subroutine
Same problem here. Zulaxia's solution of reapplying the tilemode programmatically does fix it sometimes, but often it is set back to stretch anyways. For me it only happens in a layer-list of tiled drawables that I use inside a selector state list and then apply as the background of a button. Greg's comment, that the problem might be connected to tilemode being reset in recycled views, matches what I see here quite well.Adan
Confirmed to be happening here too. It was happening in public View getView(int position, View convertView, ViewGroup parent), in my adapter.Nocturnal
Just had an email from the Android bug tracker saying this is resolved in ICS.Mud
I'm seeing this bug on GingerBread and HoneyComb. Not on Froyo, nor in later (ICS+) OS versions.Doyledoyley
C
39

I also got bitten by this problem. Very hard to diagnose, even harder to find similar reports and usable solutions.

"Tapas" on the freenode #android-dev irc channel came with the following utility method:

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);
        }
    }
}

Apply it to all Views that have a tiled background set (e.g. findViewById them).

Also, I have the impression this bug started acting up after setting "anyDensity=true" in AndroidManifest.xml

Chrysotile answered 29/2, 2012 at 13:49 Comment(2)
How do I apply it to a drawable defined in xml? I use this drawable within a <selector >Aesthetics
This solution works for me too, but view background was not set strangely so I have to add view.setBackgroundResource(R.drawable.bg_striped_img); before view.getBackground(); . Thank you :)Descendant
M
9

I've just had the exact same issue except with CLAMP TileMode. I have a bitmap that I want to then just stretch away at the bottom and have it set up as an XML defined BitmapDrawable and in the Graphical Preview window all looks fine, no matter what size I make the ViewImage it draws my bitmap at the top and then repeats the last pixels to fill to the end.

Launching the app on various SDK builds on the emulator and on my own phone all then produced a straight 'fill' type distortion which is completely useless.

The solution turned out to simply be to re-apply the TileMode every time I changed the size of the ImageView within my code:

((BitmapDrawable)ascender.getDrawable()).setTileModeY(TileMode.CLAMP);

Now it's all drawing fine. So yes, this looks like a bug to me.

Mud answered 1/5, 2011 at 23:33 Comment(0)
H
6

As I didn't see the link here, this was confirmed to be a bug in Android. It was fixed in ICS. See XML drawable Bitmap tileMode bug? for more details.

Hatten answered 18/6, 2012 at 20:47 Comment(0)
G
6

There is a lot of noise about this topic online, with various (and numerous) suggested solutions.

  • If you're still at a loss, my suggestion is to keep all tiled bitmap resources to square, base-2 dimensions.

ie: 16px by 16px for an xhdpi tile asset.

I hoped that the Android platform would "over-tile" to fill a space if the bitmap did not tessellate perfectly - and then trim the waste. However trialling a 10px*10px tiled bitmap across mdpi, hdpi and xhdpi (and v2.3 to v4.0)'inconsistently' showed this stretching.

The base-2 dimension allows for whole and even division as you progress through the various resolutions and as each device tries to paint the tiles each time the view is created.

In Android development, we contest with the ranging hardware and the vendors dipping their fingers into the platform - sometimes this sort of trivial black magic just works.

This appears to have resolved the issue for me at least. Worth a shot.

Gherlein answered 2/8, 2013 at 7:26 Comment(1)
Thanks. That saved me. But the problem seems to exists only for some specific devices. When running the same Android version and screen resolution on the emulator, it can repeat the background fine for any size i have tested.Stott
F
2

This sounds like a bug, although I've never seen it myself. If you have a simple APK that reproduces the issue, please send it to me (romainguy /at/ android.com) or file a bug here.

Feodor answered 15/2, 2011 at 17:39 Comment(1)
I'm also seeing this issue every time if I create a bitmap tiled inside one of the selector states. This is working all from xml and placing the selector on a Button or ImageButton.Stale
S
1

This blog entry discusses the issue

combined with this solution from Tapas listed by Ivo van der Wijk, it works for me.

The key was to remove the tiled setting from the XML, then set it to tiled at runtime. It does not work for me if they are both set to tiled.

Edit: actually, I lied. Even with this it seems to sometimes fail to tile.

Would be very nice to have a reliable work-around.

Edit 2: setting it to something else (eg. CLAMPED) then setting it back so far seems to be working.

Smalt answered 1/5, 2012 at 3:14 Comment(0)
C
1

I was also having the same issue. What I was missing was that we need to add scaletype to fitXY in the imageview for the xml bitmap to work properly.

tile_bitmap.xml

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

layout.xml

<ImageView
    android:layout_width="match_parent"
    android:src="@drawable/tile_bitmap"
    android:layout_height="match_parent"
    android:scaleType="fitXY"/>
Committal answered 10/10, 2017 at 9:29 Comment(0)
H
0

I moved my image from drawable-xhdpi to drawable folder and everything was fine.

Hardandfast answered 24/11, 2016 at 7:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.