更改 TextView 的下划线颜色 [英] Changing the underline color of TextView

查看:24
本文介绍了更改 TextView 的下划线颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更改 TextView 中下划线指示器的颜色.

我知道我可以给这样的文字加下划线

Spanned htmlString = Html.fromHtml("<u> <font color="#FF0000"> 一些文本 </font> </u>")someTextView.setText(htmlString);

像这样

SpannableString 内容 = new SpannableString(test);content.setSpan(new UnderlineSpan(), 0, test.length(), 0);tvTest.setText(内容);

但两种解决方案都为文本和下划线指示器使用相同的颜色.我想知道我是否可以在没有任何背景 XML 和反射黑客的情况下以理智的方式更改下划线指示器的颜色,如此处所示

  • 编辑文本.它通过在画布上手动绘制下划线,为您提供了实现这一目标所需的一切.

    首先我定义了自定义属性,以便在 XML 布局文件中轻松自定义

    <declare-styleable name="UnderlinedTextView" ><attr name="underlineWidth" format="dimension"/><attr name="underlineColor" format="color"/></declare-styleable>

    还有一个自定义的TextView

    公共类 UnderlinedTextView 扩展 AppCompatTextView {私有矩形 lineBoundsRect;私人油漆下划线油漆;公共下划线文本视图(上下文上下文){这(上下文,空,0);}public UnderlinedTextView(上下文上下文,AttributeSet attrs){这(上下文,属性,0);}public UnderlinedTextView(上下文上下文,AttributeSet attrs,int defStyleAttr){超级(上下文,属性,defStyleAttr);初始化(上下文,属性,defStyleAttr);}私有无效初始化(上下文上下文,AttributeSet attributeSet,int defStyle){浮动密度 = context.getResources().getDisplayMetrics().density;TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.UnderlinedTextView, defStyle, 0);int mColor = typedArray.getColor(R.styleable.UnderlinedTextView_underlineColor, 0xFFFF0000);浮动 mStrokeWidth = typedArray.getDimension(R.styleable.UnderlinedTextView_underlineWidth, 密度 * 2);typedArray.recycle();lineBoundsRect = new Rect();underlinePaint = new Paint();underlinePaint.setStyle(Paint.Style.STROKE);underlinePaint.setColor(mColor);//下划线颜色underlinePaint.setStrokeWidth(mStrokeWidth);}@ColorInt公共 int getUnderLineColor() {返回下划线Paint.getColor();}公共无效 setUnderLineColor(@ColorInt int mColor) {underlinePaint.setColor(mColor);无效();}公共浮动 getUnderlineWidth() {underlinePaint.getStrokeWidth()}公共无效setUnderlineWidth(浮动mStrokeWidth){underlinePaint.setStrokeWidth(mStrokeWidth);无效();}@覆盖受保护的无效onDraw(帆布画布){int count = getLineCount();最终布局布局 = getLayout();浮动 x_start,x_stop,x_diff;int firstCharInLine, lastCharInLine;for (int i = 0; i < count; i++) {int 基线 = getLineBounds(i, lineBoundsRect);firstCharInLine = layout.getLineStart(i);lastCharInLine = layout.getLineEnd(i);x_start = layout.getPrimaryHorizo​​ntal(firstCharInLine);x_diff = layout.getPrimaryHorizo​​ntal(firstCharInLine + 1) - x_start;x_stop = layout.getPrimaryHorizo​​ntal(lastCharInLine - 1) + x_diff;canvas.drawLine(x_start, 基线 + mStrokeWidth, x_stop, 基线 + mStrokeWidth, underlinePaint);}超级.onDraw(画布);}}

    那么它的用法就很简单了

    最终结果

    • 多行

    • 单行

    I am trying to change the color of the underline indicator in a TextView.

    I know I can underline text like this

    Spanned htmlString = Html.fromHtml("<u> <font color="#FF0000"> some text </font> </u>")
    someTextView.setText(htmlString);
    

    And like this

    SpannableString content = new SpannableString(test);
    content.setSpan(new UnderlineSpan(), 0, test.length(), 0);
    tvTest.setText(content);
    

    But both solutions use the same color for the text and the underline indicator. I want to know if I can change the color of the underline indicator in a sane way without any background XML and reflection hacks as seen here

    I want to underline only the text, not the paddings, margins. My text can span over multiple lines too, I want every line to be underlined. (This is where the XML solution fails).

    Result of my code

    解决方案

    It feels weird answering my own question, but for the sake of anyone having the same problem, I will. I have stumbled upon Layout class when reading some other posts for doing this on EditText. It provides everything you need to make this happen by manually drawing underline with canvas.

    First I defined custom attributes for an easy customization in XML layout files

    <declare-styleable name="UnderlinedTextView" >
        <attr name="underlineWidth" format="dimension" />
        <attr name="underlineColor" format="color" />
    </declare-styleable>
    

    And a custom TextView class

    public class UnderlinedTextView extends AppCompatTextView {
    
        private Rect lineBoundsRect;
        private Paint underlinePaint;
    
        public UnderlinedTextView(Context context) {
            this(context, null, 0);
        }
    
        public UnderlinedTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public UnderlinedTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs, defStyleAttr);
        }
    
        private void init(Context context, AttributeSet attributeSet, int defStyle) {
    
            float density = context.getResources().getDisplayMetrics().density;
    
            TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.UnderlinedTextView, defStyle, 0);
            int mColor = typedArray.getColor(R.styleable.UnderlinedTextView_underlineColor, 0xFFFF0000);
            float mStrokeWidth = typedArray.getDimension(R.styleable.UnderlinedTextView_underlineWidth, density * 2);
            typedArray.recycle();
    
            lineBoundsRect = new Rect();
            underlinePaint = new Paint();
            underlinePaint.setStyle(Paint.Style.STROKE);
            underlinePaint.setColor(mColor); //color of the underline
            underlinePaint.setStrokeWidth(mStrokeWidth);
        }
    
        @ColorInt
        public int getUnderLineColor() {
            return underlinePaint.getColor();
        }
    
        public void setUnderLineColor(@ColorInt int mColor) {
            underlinePaint.setColor(mColor);
            invalidate();
        }
    
        public float getUnderlineWidth() {
           underlinePaint.getStrokeWidth()
        }
    
        public void setUnderlineWidth(float mStrokeWidth) {
            underlinePaint.setStrokeWidth(mStrokeWidth);
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
    
            int count = getLineCount();
    
            final Layout layout = getLayout();
            float x_start, x_stop, x_diff;
            int firstCharInLine, lastCharInLine;
    
            for (int i = 0; i < count; i++) {
                int baseline = getLineBounds(i, lineBoundsRect);
                firstCharInLine = layout.getLineStart(i);
                lastCharInLine = layout.getLineEnd(i);
    
                x_start = layout.getPrimaryHorizontal(firstCharInLine);
                x_diff = layout.getPrimaryHorizontal(firstCharInLine + 1) - x_start;
                x_stop = layout.getPrimaryHorizontal(lastCharInLine - 1) + x_diff;
    
                canvas.drawLine(x_start, baseline + mStrokeWidth, x_stop, baseline + mStrokeWidth, underlinePaint);
            }
    
            super.onDraw(canvas);
        }
    }
    

    Then it's usage is simple

    <some.package.UnderlinedTextView
        android:id="@+id/tvTest"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:gravity="center"
        android:text="This is a demo text"
        android:textSize="16sp"
        app:underlineColor="#ffc112ef"
        app:underlineWidth="3dp"/>
    

    Final result

    • Multi line

    • Single line

    这篇关于更改 TextView 的下划线颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆