2015-06-08 6 views
2

Я пытаюсь изменить цвет индикатора подчеркивания в TextView.Изменение цвета подчеркивания TextView

Я знаю, что могу подчеркнуть текст, как этот

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 и отражения писак, как показано здесь

Я хочу подчеркнуть, только текст, а не прокладки, поля. Мой текст может охватывать несколько строк, я хочу, чтобы каждая строка была подчеркнута. (Здесь не удается выполнить решение XML).

Результат моего кода

enter image description here

ответ

13

Он чувствует себя странно, отвечая на мой собственный вопрос, но ради тех, кто с той же проблемой, я буду. Я наткнулся на класс Layout при чтении некоторых других сообщений для этого на EditText. Он предоставляет все необходимое для того, чтобы это произошло, вручную вычерчивая подчеркивание с помощью холста.

Сначала я определил пользовательские атрибуты для легкой настройки в файлах разметки XML

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

Final

  • многоканальная линия

    enter image description here
  • Однолинейная

    enter image description here
+0

Nice вы решили проблему? И Лучше вы поделились своими знаниями здесь ... !!! –

+0

@MohammedAli Да, я решил свою проблему. К счастью :) –

+0

Действительно хороший метод, поздравляю! Хотя у меня проблема при использовании, строка не всегда выравнивается одинаково: иногда они заканчиваются перед словом, иногда немного после. Я не знаю, может ли это быть проблемой с дополнением или чем-то еще. Вы знаете, почему это может произойти? Благодаря! – dleal

Смежные вопросы