在 TextView 上绘制背景(不是全宽)

Posted

技术标签:

【中文标题】在 TextView 上绘制背景(不是全宽)【英文标题】:Drawing background on TextView (not on its full width) 【发布时间】:2016-03-27 16:19:40 【问题描述】:

我想在 TextView 上设置背景可绘制对象(或资源),而不考虑其复合可绘制宽度(和填充)。

获取复合的宽度(更准确地说是左边的),它的填充应该不是问题,但是在textview的宽度上设置背景减去复合drawable的宽度(如上所述) .

如果您对此有任何建议,请告诉我。

这是所需的结果:

PS。我考虑过使用 ImageView 和 TextView 作为其子级的水平 LinearLayout,并且仅在 textview 上设置背景,但我有兴趣使用更少的视图(在这种情况下,正好是一个)获得相同的结果,如果它是可能。

【问题讨论】:

textview 中的背景在哪里(在需要的结果中)? @shreyansjain 在 TextView 的顶部或底部(图片中的分隔线),无论哪种方式都有效。 【参考方案1】:

您可以使用支持插入的LayerDrawable,例如:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:left="dimension" android:right="dimension">
        <shape android:shape="rectangle">
            <solid android:color="color" />
        </shape>
    </item>
</layer-list>

如果你想动态地改变你的 Drawable,你最好编写你自己的 Drawable 类。例如,以下 DividerDrawable 将一条线绘制到白色背景上的给定填充:

public class DividerDrawable extends Drawable 

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private float mDensity;
    private int mPaddingLeft = 0;

    public DividerDrawable(Context context) 
        mPaint.setColor(Color.BLACK);
        mDensity = context.getResources().getDisplayMetrics().density;
    

    @Override
    public void draw(Canvas canvas) 
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        canvas.drawColor(Color.WHITE);
        canvas.drawRect(mPaddingLeft, height - mDensity, width, height, mPaint);
    

    @Override
    public void setAlpha(int alpha) 

    

    @Override
    public void setColorFilter(ColorFilter colorFilter) 

    

    @Override
    public int getOpacity() 
        return PixelFormat.TRANSLUCENT;
    

    public void setPaddingLeft(int paddingLeft) 
        if (mPaddingLeft != paddingLeft) 
            mPaddingLeft = paddingLeft;
            invalidateSelf();
        
    

要根据您的左侧 CompoundDrawable 设置左侧填充,您可以执行以下操作:

private void setBackground(TextView textView, DividerDrawable background) 
    Drawable drawableLeft = textView.getCompoundDrawables()[0];
    int paddingLeft = drawableLeft != null ?
            textView.getPaddingLeft() + drawableLeft.getIntrinsicWidth() + textView.getCompoundDrawablePadding() :
            textView.getPaddingLeft();
    background.setPaddingLeft(paddingLeft);
    textView.setBackground(background);

为了充分利用这一切,这样称呼它:

    DividerDrawable dividerDrawable = new DividerDrawable(this);
    TextView textView = (TextView) findViewById(R.id.text);
    setBackground(textView, dividerDrawable);

【讨论】:

谢谢。在你的帮助下,我设法做到了。我还要问你一件事:每次我在 TextView 上设置(或更改其位置)可绘制对象(包括来自 xml)时,是否都会调用一种方法。即:setCompoundDrawables / setCompoundDrawablesRelative,还是我需要覆盖每一个并计算新的宽度和填充? 抱歉,我不太关注你。如果您调用 setCompoundDrawables(),将调用 requestLayout() 来处理更改(测量、布局和绘图)。你想达到什么目的? 我的意思是把左边的插图添加到 layerdrawable 的最佳位置在哪里,所以只要左边的 drawable 可见/消失或放置在其他地方,它就会自动改变自己?正如我试图在我的问题中解释的那样,我需要这条灰线不显示在图标上,而只显示在文本上。 你可以为每个状态创建一个drawable并在它们之间切换,或者甚至可以编写你自己的Drawable类。 我设法通过设置带有左填充的可绘制图层列表的背景来做到这一点。我有兴趣动态设置图层列表可绘制的左侧填充(每当我在 TextView 上设置左侧可绘制或左侧填充时,背景(视图顶部的分隔线)应相应缩小其宽度。你能帮我吗用那个?

以上是关于在 TextView 上绘制背景(不是全宽)的主要内容,如果未能解决你的问题,请参考以下文章

div全宽的响应式背景图像

Android TextView以编程方式跨越全宽

Android L 忽略形状作为可绘制背景

设计模式 策略模式 以Android 中TextView绘制文本颜色为背景说明

背景图像在 Safari 和 iOS 中未显示全宽

div上的全宽背景颜色