自定义View-字体变色(一个文字两种颜色)
思路:主要是画笔Paint的使用和Canvas的裁切,需要继承自TextView。
一个文字两种颜色
颜色不同的朝向
与ViewPager整合
一种文字两种颜色
自定义文字颜色属性,两种颜色,一个是原始颜色,一个是变化的颜色
1 2 3 4 5 6 <resources > <declare-styleable name ="ColorTrackTextView" > <attr name ="originColor" format ="color" /> <attr name ="changeColor" format ="color" /> </declare-styleable > </resources >
自定义ColorTrackTextView继承自TextView,获取自定义属性中的属性。初始化两支Paint,绘制两种颜色。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 private Paint mOrignPaint;private Paint mChangePaint;private void initPaint (Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView); int originColor = typedArray.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor()); int changeColor = typedArray.getColor(R.styleable.ColorTrackTextView_changeColor, getTextColors().getDefaultColor()); mOrignPaint = getPaintByColor(originColor); mChangePaint = getPaintByColor(changeColor); typedArray.recycle(); } private Paint getPaintByColor (int color) { Paint paint = new Paint(); paint.setColor(color); paint.setAntiAlias(true ); paint.setDither(true ); paint.setTextSize(getTextSize()); return paint; }
一个文字不同颜色的实现主要是通过canvas.clipRect()来实现,通过裁切不同的文字部分然后使用不同颜色的画笔进行实时绘制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private void drawText (Canvas canvas,Paint paint,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(); paint.getTextBounds(text, 0 , text.length(), bounds); int x = getWidth() / 2 - bounds.width() / 2 ; Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt(); int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; int baseline = getHeight() / 2 + dy; canvas.drawText(text, x, baseline, paint); canvas.restore(); }
1 2 3 4 5 6 7 8 <com.sx.colortext.ColorTrackTextView android:layout_width ="wrap_content" android:layout_height ="wrap_content" app:changeColor ="@color/colorAccent" app:originColor ="@color/colorPrimary" android:text ="Hello World!" android:textSize ="20sp" />
颜色不同朝向的实现
不同朝向的实现其实就是指定起始点与重点的位置即可。
1 2 3 4 5 private Direction mDirection = Direction.LEFT_TO_RIGHT;public enum Direction { LEFT_TO_RIGHT, RIGHT_TO_LEFT }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override protected void onDraw (Canvas canvas) { int middle = (int ) (mCurrentProgress * getWidth()); if (mDirection == Direction.LEFT_TO_RIGHT) { drawText(canvas, mChangePaint, 0 , middle); drawText(canvas, mOrignPaint, middle, getWidth()); } else if (mDirection == Direction.RIGHT_TO_LEFT) { drawText(canvas, mChangePaint, getWidth()-middle, getWidth()); drawText(canvas, mOrignPaint, 0 , getWidth()-middle); } }
在为ColorTrackTextView对外提供两个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void setDirection (Direction direction) { this .mDirection = direction; } public void setCurrentProgress (float progress) { this .mCurrentProgress = progress; invalidate(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void rightToLeft (View view) { mTrackTextView.setDirection(ColorTrackTextView.Direction.RIGHT_TO_LEFT); ObjectAnimator animator = ObjectAnimator.ofFloat(mTrackTextView, "translationX" , 0 , 1 ); animator.setDuration(2000 ); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate (ValueAnimator animation) { float fraction = animation.getAnimatedFraction(); mTrackTextView.setCurrentProgress(fraction); } }); animator.start(); }
采用LinearLayout动态添加View的方式配合ViewPager+Fragment实现效果,最后实现的效果如下图