Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background drawables define view size

Tags:

android

For the sake of clarity, this question has been edited significantly.

Let's say I have a .png resource of 100x100px:
enter image description here

I want to use that image as a background for my TextViews, which size is determined by its content, which is variable at runtime. Especially, I want that image to tile when the TextView size is larger than 100x100px, and I want it to be cropped when the TextView is smaller than 100x100px.

The latter seems to be a difficult one.

Example code

I have a drawable resource bg_tile.xml:

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

My layout file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:background="@drawable/bg_tile"
        android:text="Short text"
        android:textSize="20sp" />

    <TextView android:layout_margin="8dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_tile"
        android:text="Long text long text long text long text long text long text long text long text long textlong text long text long text long text long text long text long text long text long textlong text long text long text long text long text long text long text long text long text "
        android:textSize="20sp" />

</LinearLayout>

What's happening

Here is a screenshot of the result of this code, and one of what I would expect / what I want: enter image description here

As you can see, the tiling part works, and the bottom tile is being cut off. However, when the TextView is smaller than the background, the TextView takes the size of the background.

Suggested solutions

  • android:gravity="clip_vertical|clip_horizontal" - This doesn't work, even without tilemode.
  • Use match_parent as layout params - Not an option.
  • Setting a fixed height - There is no way of telling how long the content of the TextView will be, and with that its size.

How can I achieve my goal?

like image 611
nhaarman Avatar asked Feb 20 '13 09:02

nhaarman


People also ask

How do you change drawable size on android?

Once you import svg file into Android Studio project, you are going to see <vector> resource then just change the size as you want by width , height attributes. viewportWidth and viewportHeight is to set size for drawing on virtual canvas.

What is the best image size for Android?

The best image resolution for most smartphones is 640 by 320 pixels, although you should ideally maintain the aspect ratio of the original image or the output image will be distorted.

What is the preferred image format for Drawables?

Supported file types are PNG (preferred), JPG (acceptable), and GIF (discouraged). App icons, logos, and other graphics, such as those used in games, are well suited for this technique.


1 Answers

I have not tried this myself, but you could try this idea/hack/workaround:

The minimum height/width of a View (TextView) is determined by its background drawable (amongst other things). It uses the background Drawable's getMinimumHeight() and getMinimumWidth() to determine the View's minimum height and width.

It looks like you want the View's minimum height and width to be 0 (excluding padding) and the View's width/height should be based only on the View's content (in your case, the TextView's text).

Try this in the onCreate of your Activity or the onCreateView of your Fragment, where you get a hold of the TextView you are trying to 'fix'. Let's call this TextView 'tv':

TextView tv; 
...
...
tv = (TextView)...findViewById(...);
....

// Swap the 'standard' bitmap background with one that has no minimum width/height.
BitmapDrawable background = (BitmapDrawable)tv.getBackground(); // assuming you have bg_tile as background.
BitmapDrawable newBackground = new BitmapDrawable(background.getBitmap) {
    @Override
    public int getMinimumWidth() {
        return 0;
    }

    @Override
    public int getMinimumHeight() {
        return 0;
    }
};
newBackground.setTileModeXY(background.getTileModeX(), background.getTileModeY());
tv.setBackgroundDrawable(newBackground);
...
...
like image 149
Streets Of Boston Avatar answered Sep 24 '22 13:09

Streets Of Boston