Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tiled background is pushing it's View size

I have a tiled bitmap that I'm using as the View background. This View, let's say, has android:layout_height="wrap_content". The problem is that the height of the bitmap used in the background is participating in the measurement of the view, increasing the View height. This can be noticed when the size of the content of View is smaller than the height of the bitmap used as the tile background.

Let me show you an example. The tile bitmap:

enter image description here

The bitmap drawable (tile_bg.xml):

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

The layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#FFFFFF">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/tile_bg"
        android:text="@string/hello"
        android:textColor="#000000" />

</LinearLayout>

How it looks like:

enter image description here

The height of the TextView ends up being the height of the bitmap. What I was expecting is that the bitmap gets clipped to the size of the View.

Is there any way to achieve this?

Notes:

  • I can't use 9patch drawables since the background needs to be repeated in a tile fashion way, stretching is not an option.
  • I can't set a fixed height for the View, it depends of the children (I'm using this in a ViewGroup)
  • This odd behavior happens as I explained before when the size of the View is smaller than the size of the bitmap, otherwise the bitmap is repeated an clipped correctly (ie, if the view size is 1.5x the size of the bitmap, you end up seeing 1.5 times the bitmap).
  • The example deals with the height, but is the same using the width.
like image 903
aromero Avatar asked Jan 12 '12 21:01

aromero


1 Answers

You need a custom BitmapDrawable that returns 0 from getMinimumHeight() and getMinimumWidth(). Here's one I've named BitmapDrawableNoMinimumSize which does the job:

import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;

public class BitmapDrawableNoMinimumSize extends BitmapDrawable {

    public BitmapDrawableNoMinimumSize(Resources res, int resId) {
        super(res, ((BitmapDrawable)res.getDrawable(resId)).getBitmap());
    }

    @Override
    public int getMinimumHeight() {
        return 0;
    }
    @Override
    public int getMinimumWidth() {
         return 0;
    }
}

Of course you can't (AFAIK) declare custom drawables in XML, so you have to instantiate and set the textview's background thusly:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    BitmapDrawable bmpd =new BitmapDrawableNoMinimumSize(getResources(), R.drawable.tile);
    bmpd.setTileModeX(TileMode.REPEAT);
    bmpd.setTileModeY(TileMode.REPEAT);
    findViewById(R.id.textView).setBackgroundDrawable(bmpd);
}

And of course you remove the background attribute from the layout xml:

<TextView
    android:id="@+id/textView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Testing testing testing"
    android:textColor="#000000" />

I've tested this and it seems to work.

like image 182
Reuben Scratton Avatar answered Sep 24 '22 02:09

Reuben Scratton