android:文本视图中DrawableLeft的适合高度

android:文本视图中DrawableLeft的适合高度,android,drawable,Android,Drawable,我试图在文本块旁边显示一条蓝线,大致如下: 这是我的密码: <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableLeft="@drawable/blue_line" /> 蓝线是一个

我试图在文本块旁边显示一条蓝线,大致如下:

这是我的密码:

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

蓝线是一个jpg文件。蓝色的长方形。无论文本视图中的文本是什么,它都以其原始大小显示。如何根据文本的高度动态调整其高度?例如,当文本数量较少时,将其缩短,当文本数量较多时,将其延长……

请尝试以下操作

<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>

您需要创建一个左蓝线右文本视图的水平XML布局。
然后像使用项目一样使用该布局,并创建这些项目的列表视图。类似于,但简单一点

您可以通过设置图像的边界,在代码中尝试这样做

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

简单地说,让您的图像保持可绘制状态

您可以将android:drawableLeft=“@drawable/checkmark”添加到您的文本视图中。您还可以设置
drawablePadding
,以保持文本视图的组织

android:drawableLeft="@drawable/button_icon"
android:drawablePadding="2dip"
下面是创建9patch的链接


最好的方法是将可绘制文件包装在xml可绘制文件中,并在文本视图中将其设置为可绘制文件,如下所示:

可绘制XML文件:

<?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"/>

XML格式的文本视图:

<TextView 
    android:id="@+id/title_total_cal"
    style="@style/title_stats_textview"
    android:drawableLeft="@drawable/total_calories_drawable"/>

您可以在可绘制画布上绘制一条具有所需高度的线,并将其设置为文本视图的左侧可绘制。看看这个:

public class FullHeightLineDrawable extends Drawable {
    private Paint mPaint;
    private int mHeight;

    public FullHeightLineDrawable(int height) {
        mPaint = new Paint();
        mPaint.setColor(CompatUtils.getColor(R.color.colorAccent));
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(15);

        mHeight = height;
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawLine(0, -mHeight, 0, mHeight, mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
    }

    @Override
    public int getOpacity() {
        return 0;
    }
}
用法:

final Drawable drawable = new FullHeightLineDrawable(getHeight());
mTextView.setTextColor(watchingColor);
mTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);

我抽象出这个方法。当drawable位于TextView的左侧时,它会工作,动态缩放。如果drawable位于右侧,则此方法不起作用,需要找出原因,但您可以直接使用
textView.setcompounddrawableswithintrinsicbounds()
和大小合适的drawable资源

@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
public static void ajustCompoundDrawableSizeWithText(final TextView textView, final Drawable leftDrawable, final Drawable topDrawable, final Drawable rightDrawable, final Drawable bottomDrawable) {
    textView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
           if(leftDrawable != null){
               leftDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
           }
            if(topDrawable != null){
                topDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
            }
            if(rightDrawable != null){
                rightDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
            }
            if(bottomDrawable != null){
                bottomDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
            }
            textView.setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
                textView.removeOnLayoutChangeListener(this);
        }
    });
}

我创建了一个类,该类扩展了
TextView
,并在
onpredrawstener
中调整了可绘图项的大小

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;
            }
        });
    }
}
不幸的是,挫折对我不起作用,所以我不得不做一些变通

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

这并不是关于性能的最佳解决方案,因为创建了新位图,但仍然有效。

使用QuoteSpan或LeadingMarginSpan之一我尝试了QuoteSpan它看起来很棒,但是有没有办法增加线条的宽度?如何使用leadingmarginspan?我认为这可能是一个精确的解决方法:尝试设置素描,如果拉伸或挤压,则选择9patch@Tekno Freek.你测试过这个吗?不适用于我(但应用于按钮)。图像仍然被裁剪。请在新的问题中发布您的XML。也许您需要查看您的主题是否限制了这一点。这个问题大约在4年前得到了回答,所以发生了很大的变化。此外,按钮可能需要不同的XML覆盖来处理不同的按下状态。@Shan Xeeshi您尝试了什么?请记住,在位图XML中,您不使用其他XML可绘制作为源可绘制。要使用此解决方案,您应该使用PNG或JPG drawables。在我的情况下,此视图的父容器是view.GONE on create。这将导致getMeasuredHeight()==0,并且图像的大小也为零。我使用textView1.getLineHeight()而不是textView1解决了这个问题。getMeasuredHeight()在这两种情况下都是如此。为什么必须在“onGlobalLayout”中执行此操作?当第一次将图像设置为可计算绘制时,不仅仅是在“onCreate”中?@EladBenda这需要在OnGlobalLayoutListener中完成,因为这是在绘制视图时调用的,只有在绘制视图时才能获得正确的视图高度和宽度。在onCreate方法中,视图尚未绘制,因此您将得到高度和宽度为0。
// 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);