Android 自定義View 字型變色

weixin_34393428發表於2018-01-23

1.效果

5876940-28bba8688fc96a9d.png
image.png

2.根據效果,分析如實現

效果是,文字自做導遊逐漸變色,用TextView無法實現,這裡採用自定義View,讓他繼承自TextView,這樣的話,就不需要再重寫onMeasure()方法,這裡,我們只需要自定義兩張字型顏色(預設顏色和要變色的顏色就可)。

3.程式碼實現

3.1 自定義屬性

在valuse目錄下建立attrs.xml檔案,在裡面建立自定義屬性

  <declare-styleable name="ColorTrackTextView">
    <attr name="cmOriginTextColor" format="color"></attr>
    <attr name="cmChangeTextColor" format="color"></attr>
</declare-styleable>
3.2 在佈局中呼叫
        <com.test.cmviewdemo.ColorTrackTextView
            android:text="@string/app_name"
            android:id="@+id/main_TrackTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:textSize="22sp"
            app:cmChangeTextColor="@color/colorAccent"
            app:cmOriginTextColor="@color/colorPrimary" />
3.3 建立自定義View類,並繼承自TextView

public class ColorTrackTextView extends AppCompatTextView {

public ColorTrackTextView(Context context) {
    this(context,null);
}

public ColorTrackTextView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs,0);
}

public ColorTrackTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

  }
}
3.4 建立畫筆(在構造方法中呼叫initPaint()方法,建立畫筆)
private Paint cmOriginTextPaint;
private Paint cmChangeTextPaint;

private void initPaint(Context context, AttributeSet attrs) {
    //獲取自定義屬性
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);
    int cmOriginTextColor = typedArray.getColor(R.styleable.ColorTrackTextView_cmOriginTextColor, getTextColors().getDefaultColor());
    int cmChangeTextColor = typedArray.getColor(R.styleable.ColorTrackTextView_cmChangeTextColor, getTextColors().getDefaultColor());
    typedArray.recycle();

    //根據自定義的顏色來建立畫筆
    cmOriginTextPaint = getTextPaintByColor(cmOriginTextColor);
    cmChangeTextPaint = getTextPaintByColor(cmChangeTextColor);

}
3.5 重寫onDray()方法,從新繪製Text
  /**
 * 根據自定義畫筆,重寫onDray()方法,重寫繪製
 * @param canvas
 */
@Override
protected void onDraw(Canvas canvas) {

    //根據當前進度,獲取當前中間值
    int middle = (int) (cmCurrentProgress * getWidth());

    //根據朝向,繪製TextView
    if(Directory.LEFT_TO_RIGHT == cmCurrentDirectory){
        //當前朝向為  從左到右
        drawText(canvas,cmChangeTextPaint,0,middle);
        drawText(canvas,cmOriginTextPaint,middle,getWidth());
    }else{
        //當前朝向  從右到左
        drawText(canvas,cmChangeTextPaint,getWidth() - middle,getWidth());
        drawText(canvas,cmOriginTextPaint,0,getWidth()-middle);
    }

}


  /**
 * 繪製TextView
 * @param canvas
 * @param textPaint
 * @param start
 * @param end
 */
private void drawText(Canvas canvas, Paint textPaint, int start, int end) {

    //儲存畫布狀態
    canvas.save();

    Rect rect = new Rect(start,0,end,getHeight());
    canvas.clipRect(rect);

    //獲取文字
    String text = getText().toString();

    Rect bounds = new Rect();
    textPaint.getTextBounds(text,0,text.length(),bounds);

    //獲取字型的寬度
    int x = getWidth()/2 - bounds.width()/2;
    //獲取基線
    Paint.FontMetricsInt fontMetricsInt = textPaint.getFontMetricsInt();
    int dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom;
    int baseLine = getHeight()/2 + dy;

    canvas.drawText(text,x,baseLine,textPaint);

    //釋放畫布狀態,既恢復Canvas旋轉,縮放等之後的狀態。
    canvas.restore();
}

4

Github Demo 地址
https://github.com/hualianrensheng/CMViewDemo

引用
https://www.jianshu.com/p/2ff454ae6036

相關文章