Repeated background image is stretched

I'm having quite a hard time with a textured background. I have a 60px by 60px bitmap texture that I want to set as the background for my layout in a repeated tile pattern. Here's the layout xml located in res/layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/dark_texture_background" >

    ...
</RelativeLayout

And here is the dark_texture_background, located in res/drawable:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/dark_background_texture"
    android:tileMode="repeat" />

The dark_background_texture is the 60x60 pixel image.

So, the issue is that the texture image is being enlarged while also being tiled. I added a red line to the outside of the texture image to see exactly where the texture images were, and here's the result:

I also added the screen height, width and density according to getResources().getDisplayMetrics().

Since the screen width is 480 pixels, the texture image should be repeated 8 times across (480 / 60 = 8). Instead, there are only 5 ~1/4. The image is now ~90 pixels and tiled. WTF?

Why is my texture image being stretched when I explicitly tell it to repeat?

Answers


I'm not sure what Raghav's referring to with the bug, exactly, but if they've changed something in ICS+ then there was certainly something wrong. That said, I'm fairly certain that bitmap images in drawable are assumed to be mdpi, and scaled from there (maybe they changed that behavior?), which makes sense given that your 60px image became 90px (60 * 1.5 scaling factor).

You can avoid scaling altogether, keeping in mind that the physical size will differ on different densities (although for a tiled background it's probably not important), by placing your bitmaps into a drawable-nodpi folder only. Android will use those drawables without scaling, regardless of density.


This is a bug in the Android framework, that was fixed ICS onwards. Anyhow, here's the rough workaround for pre ICS versions:

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 (i.e. findViewById() them).

Sometimes, the bug starts acting up after setting anyDensity=true in AndroidManifest.xml


Need Your Help

Which STL to use to find index by value in O(1) in C++

c++ algorithm stl

Say I have an array arr[] = {1 , 3 , 5, 12124, 24354, 12324, 5}

angularjs scope for ngModel is not working as expected

javascript angularjs angularjs-directive angularjs-scope ionic-framework

I have created custom directive drop down in angularjs and ionic-framework. In my dropdown items will open in modal popup which is working very good.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.