android: fit height of DrawableLeft in a textView

2020-02-20 07:10发布

I am trying to display a blue line next to a block of text, pretty much like this:

enter image description here

Here's my code:

<TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableLeft="@drawable/blue_line" />

blue_line is a jpg file. a blue rectangle. it displays in its original size regardless of the text in the textview. how can i adjust its height dynamically according to the height of the text? like make it shorter when theres little amount of text and longer when there's more text....

9条回答
冷血范
2楼-- · 2020-02-20 07:35

Try as below...

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:src="@drawable/btndr" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/imageView" />

</RelativeLayout>
查看更多
戒情不戒烟
3楼-- · 2020-02-20 07:35

I Created a class that extends TextView, and resize the drawables in onPreDrawListener.

public class MyTextView extends AppCompatTextView {

    public MyTextView(Context context, AttributeSet attrs, int style) {
        super(context, attrs, style);
        fitCompoundDrawableToLineHeight();
    }

    private void fitCompoundDrawableToLineHeight() {
        OnPreDraw.run(this, () -> {
            final Drawable[] cd = getCompoundDrawables();
            Arrays.stream(cd)
                .filter(drawable -> drawable != null)
                .forEach(d -> d.setBounds(0, 0, getLineHeight(), getLineHeight()));
            setCompoundDrawables(cd[0], cd[1], cd[2], cd[3]);
        });
    }
}

// Convenience class that abstracts onPreDraw logic
public class OnPreDraw {
    public static void run(View view, Runnable task) {
        view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                if (!view.getViewTreeObserver().isAlive()) {
                    return true;
                }
                view.getViewTreeObserver().removeOnPreDrawListener(this);
                task.run();
                return true;
            }
        });
    }
}
查看更多
We Are One
4楼-- · 2020-02-20 07:39

You can try doing it in code by setting bounds for the image

textView1.getViewTreeObserver()
        .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Drawable img = ActivityName.this.getContext().getResources().getDrawable(
                R.drawable.blue_line);
            img.setBounds(0, 0, img.getIntrinsicWidth() * textView1.getMeasuredHeight() / img.getIntrinsicHeight(), textView1.getMeasuredHeight());
            textView1.setCompoundDrawables(img, null, null, null);
            textView1.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
查看更多
Rolldiameter
5楼-- · 2020-02-20 07:39

You need to make a one horizontal XML layout that has the blue line left and a textview right. Than use that layout like an item and make a ListView of those items. Something like here, but a bit simpler

查看更多
神经病院院长
6楼-- · 2020-02-20 07:46

Unfortunately, setBounds was not working for me so I had to do a workaround.

// Turn wanted drawable to bitmap
Drawable dr = getResources().getDrawable(R.drawable.somedrawable);
Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();

// I had a square image with same height and width so I needed only TextView height (getLineHeight)
int size = textView1.getLineHeight();
Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, size, size, true));
textView1.setCompoundDrawables(d, null, null, null);

// Now we can set some spacing between text and image
textView1.setCompoundDrawablePadding(10);

It is not the best solution regarding performance because new bitmap is created, but still works.

查看更多
The star\"
7楼-- · 2020-02-20 07:49

The best way to do this is to wrap your drawable in an xml drawable file and set it as a drawable in your text view as follows:

Drawable XML File:

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

TextView in XML:

<TextView 
    android:id="@+id/title_total_cal"
    style="@style/title_stats_textview"
    android:drawableLeft="@drawable/total_calories_drawable"/>
查看更多
登录 后发表回答