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

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

问题描述

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

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

像这样

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

但是,两种解决方案的文字和下划线指示符使用相同的颜色.我想知道是否可以以一种合理的方式更改下划线指示器的颜色,而不会出现如此处所示的任何背景XML和反射hacks

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

我只想在文本上加下划线,而不是填充文字,下划线.我的文字也可以跨越多行,我希望每行都加下划线. (这是XML解决方案失败的地方.)

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

推荐答案

回答我自己的问题感觉很奇怪,但是为了任何人遇到同样的问题,我都会这样做.在阅读其他有关此操作的帖子时,我偶然发现了 Layout EditText.通过使用画布手动绘制下划线,它提供了实现此功能所需的一切.

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.

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

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>

和一个自定义的TextView

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

然后它的用法很简单

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

最终结果

  • 多行

  • 单行

  • Multi line

  • Single line

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

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