又是一天过去了,已经坚持写博客三天了,因为之前在研究自定义view,所以也积累了很多demo了,都是借鉴大神的然后自己敲了很多遍的东西,以前敲完都没什么感觉的,所以还是需要静下心总结一下的,于是我开始写博客了。
废话不多说了,进入我们今天的主题(变色TextView及ViewPager指示器),以前都是用github上面的ViewPagerIndicator,只管用了,感觉很高大上的东西,于是自己开始模仿一下啦,,现在还只能说是模仿.^~^!
先看一下运行的效果

思路:
比如绘制一个“helloword!”我们想”hello”为红色,“word!”为黑色,则通过canvas的clipRect方法裁剪画布,裁剪的前部分画笔用红色绘制,后半部分用黑色绘制,不断的改变progress(0~1)的值,来绘制变红的和为变红的地方。
attr文件:

  <attr name="change_icon" format="reference"></attr><attr name="change_color" format="color"></attr><attr name="change_text" format="string"></attr><attr name="text_size" format="dimension"></attr><declare-styleable name="changeTextColor"><attr name="change_icon"></attr><attr name="change_color"></attr><attr name="change_text"></attr><attr name="text_size"></attr></declare-styleable>

第一步:老套路了,我们创建一个叫FadeView的extends View,然后覆盖三个构造方法。

/*** Author:Yqy* Date:2016-07-27* Desc:渐变view* Company:cisetech*/
public class FadeView extends View{/*** 需要绘制的文本*/private String mText="测试";/*** 绘制的画笔*/private Paint mPaint;/*** 文本size*/private float mTextSize= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,14.5f,getResources().getDisplayMetrics());/*** 未变的text的颜色*/private int originTextColor= Color.BLACK;/*** 变换text的颜色*/private int changeTextColor=Color.RED;/*** text颜色变换的方向,是从左到右还是反之*/private DIRECTION mDirection=DIRECTION.LEFT;/*** 文本绘制的开始位置*/private int mTextStartX;/*** 颜色变换的进度*/private float mProgress;/*** 文字的宽度*/private int mTextWidth;
public FadeView(Context context) {this(context, null);}public FadeView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public FadeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);obtainAttr(context, attrs, defStyleAttr);initView();}/*** 初始化*/private void initView() {mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setStyle(Paint.Style.FILL);mPaint.setDither(true);mPaint.setTextSize(mTextSize);}/*** 枚举类,变换颜色的方向*/public enum DIRECTION{LEFT,RIGHT;}
}

第二步:获取参数

private void obtainAttr(Context context, AttributeSet attrs, int defStyleAttr) {TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.fadeView, defStyleAttr, 0);for (int i = 0; i <a.getIndexCount() ; i++) {int attr=a.getIndex(i);switch (attr){case R.styleable.fadeView_fadeText:mText=a.getString(attr);break;case R.styleable.fadeView_changeColor:changeTextColor=a.getColor(attr, changeTextColor);break;case R.styleable.fadeView_originColor:originTextColor=a.getColor(attr, originTextColor);break;case R.styleable.fadeView_textSize:mTextSize=a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14.5f, getResources().getDisplayMetrics()));break;case R.styleable.fadeView_direction:int flag = a.getInt(attr, 1);if(flag==1){mDirection=DIRECTION.LEFT;}else{mDirection=DIRECTION.RIGHT;}break;}}a.recycle();}

第三步:重写onMeasure方法,测量View,告诉父控件自己需要多大位置。

  @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {mTextWidth= (int) mPaint.measureText(mText,0,mText.length());int width=measureWidth(widthMeasureSpec);int height=measureHeight(heightMeasureSpec);mTextStartX=width/2-mTextWidth/2;setMeasuredDimension(width,height);}/**** @param heightMeasureSpec* @return 测量过后的height*/private int measureHeight(int heightMeasureSpec) {int result;int mode=MeasureSpec.getMode(heightMeasureSpec);int size=MeasureSpec.getSize(heightMeasureSpec);/*** 当为确定值的时候就取确定值,* 当不确定的时候大小就用文本的高度* (int) (mPaint.getFontMetrics().bottom-mPaint.getFontMetrics().top);* 方法可以获取文本宽度*/if(mode==MeasureSpec.EXACTLY){result=size;}else{result= (int) (mPaint.getFontMetrics().bottom-mPaint.getFontMetrics().top);}result=mode==MeasureSpec.AT_MOST?Math.min(result,size):result;return result+getPaddingTop()+getPaddingBottom();}/**** @param widthMeasureSpec* @return 测量过后的width*/private int measureWidth(int widthMeasureSpec) {int result;int mode=MeasureSpec.getMode(widthMeasureSpec);int size=MeasureSpec.getSize(widthMeasureSpec);/*** 当为确定值的时候就取确定值,* 当不确定的时候大小就用文本的大小* mPaint.measureText方法可以获取文本宽度*/if(mode==MeasureSpec.EXACTLY){result=size;}else{result= (int) mPaint.measureText(mText,0,mText.length());}result=mode==MeasureSpec.AT_MOST?Math.min(result,size):result;return result+getPaddingLeft()+getPaddingRight();}

补充一下,关于drawText的一些知识,可以参考我师父的神作,自定义控件之绘图篇( 五):drawText()详解

第四步:关键一步咯,重写onDraw方法,绘制我们的文本

 /*** 从startX裁剪到endX范围绘制文本*/private void drawText(Canvas canvas,int color, int startX, int endX) {mPaint.setColor(color);canvas.save(Canvas.CLIP_SAVE_FLAG);canvas.clipRect(startX, 0, endX, getMeasuredHeight());/*** 绘制文本的y坐标,看不懂的话可以看我师傅的神作,博客有给出链接*/int baseY= (int) (getMeasuredHeight()/2+(mPaint.getFontMetrics().bottom-mPaint.getFontMetrics().top)/2-mPaint.getFontMetrics().bottom);canvas.drawText(mText,mTextStartX,baseY,mPaint);canvas.restore();}

第五步:测试一下我们的成果(偷下懒,用属性动画测试了)

 public FadeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);obtainAttr(context, attrs, defStyleAttr);initView();/测试startAnima();}
public void startAnima(){ValueAnimator animator=ValueAnimator.ofFloat(0,1.0f);animator.setDuration(1500);animator.setInterpolator(new AccelerateDecelerateInterpolator());animator.setRepeatMode(ValueAnimator.RESTART);animator.setRepeatCount(ValueAnimator.INFINITE);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (float) animation.getAnimatedValue();postInvalidate();}});animator.start();}

今天太累了,明天继续写接下来的Viewpager指示器部分,不过到了这里我们也成功了一半了额,因为指示器无非就是在顶部绘制一条线。
附上FadeView全部代码:

package com.cisetech.customer.customer.View;import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;import com.cisetech.customer.customer.R;/*** Author:Yqy* Date:2016-07-27* Desc:渐变view* Company:cisetech*/
public class FadeView extends View{/*** 需要绘制的文本*/private String mText="测试";/*** 绘制的画笔*/private Paint mPaint;/*** 文本size*/private float mTextSize= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,14.5f,getResources().getDisplayMetrics());/*** 未变的text的颜色*/private int originTextColor= Color.BLACK;/*** 变换text的颜色*/private int changeTextColor=Color.RED;/*** text颜色变换的方向,是从左到右还是反之*/private DIRECTION mDirection=DIRECTION.LEFT;/*** 文本绘制的开始位置*/private int mTextStartX;/*** 颜色变换的进度*/private float mProgress;/*** 文字的宽度*/private int mTextWidth;public FadeView(Context context) {this(context, null);}public FadeView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public FadeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);obtainAttr(context, attrs, defStyleAttr);initView();/测试//startAnima();}public synchronized  void setmProgress(float mProgress) {this.mProgress = mProgress;flushView();}public DIRECTION getmDirection() {return mDirection;}public void setmDirection(DIRECTION mDirection) {this.mDirection = mDirection;}private void flushView() {mTextWidth= (int) mPaint.measureText(mText,0,mText.length());if(Looper.getMainLooper()==Looper.myLooper()){invalidate();}else{postInvalidate();}}private void obtainAttr(Context context, AttributeSet attrs, int defStyleAttr) {TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.fadeView, defStyleAttr, 0);for (int i = 0; i <a.getIndexCount() ; i++) {int attr=a.getIndex(i);switch (attr){case R.styleable.fadeView_fadeText:mText=a.getString(attr);break;case R.styleable.fadeView_changeColor:changeTextColor=a.getColor(attr, changeTextColor);break;case R.styleable.fadeView_originColor:originTextColor=a.getColor(attr, originTextColor);break;case R.styleable.fadeView_textSize:mTextSize=a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14.5f, getResources().getDisplayMetrics()));break;case R.styleable.fadeView_direction:int flag = a.getInt(attr, 1);if(flag==1){mDirection=DIRECTION.LEFT;}else{mDirection=DIRECTION.RIGHT;}break;}}a.recycle();}/*** 初始化*/private void initView() {mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setStyle(Paint.Style.FILL);mPaint.setDither(true);mPaint.setTextSize(mTextSize);}public String getmText() {return mText;}public void setmText(String mText) {this.mText = mText;mTextWidth= (int) mPaint.measureText(mText,0,mText.length());postInvalidate();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {mTextWidth= (int) mPaint.measureText(mText,0,mText.length());int width=measureWidth(widthMeasureSpec);int height=measureHeight(heightMeasureSpec);mTextStartX=width/2-mTextWidth/2;setMeasuredDimension(width,height);}/**** @param heightMeasureSpec* @return 测量过后的height*/private int measureHeight(int heightMeasureSpec) {int result;int mode=MeasureSpec.getMode(heightMeasureSpec);int size=MeasureSpec.getSize(heightMeasureSpec);/*** 当为确定值的时候就取确定值,* 当不确定的时候大小就用文本的高度* (int) (mPaint.getFontMetrics().bottom-mPaint.getFontMetrics().top);* 方法可以获取文本宽度*/if(mode==MeasureSpec.EXACTLY){result=size;}else{result= (int) (mPaint.getFontMetrics().bottom-mPaint.getFontMetrics().top);}result=mode==MeasureSpec.AT_MOST?Math.min(result,size):result;return result+getPaddingTop()+getPaddingBottom();}/**** @param widthMeasureSpec* @return 测量过后的width*/private int measureWidth(int widthMeasureSpec) {int result;int mode=MeasureSpec.getMode(widthMeasureSpec);int size=MeasureSpec.getSize(widthMeasureSpec);/*** 当为确定值的时候就取确定值,* 当不确定的时候大小就用文本的大小* mPaint.measureText方法可以获取文本宽度*/if(mode==MeasureSpec.EXACTLY){result=size;}else{result= (int) mPaint.measureText(mText,0,mText.length());}result=mode==MeasureSpec.AT_MOST?Math.min(result,size):result;return result+getPaddingLeft()+getPaddingRight();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);/*** 判断绘制变化的方向,*/if(mDirection==DIRECTION.LEFT){drawChangeLeft(canvas);drawOriginLeft(canvas);}else{drawOriginRight(canvas);drawChangeRight(canvas);}}/*** 当绘制位置为DIRECTION.RIGHT的时候* 绘制变换的部分,也就是红色部分* 裁剪的起始位置为:mTextStartX + ((1-mProgress )* mTextWidth)。* 终止位置为:mTextWidth + mTextStartX*/private void drawChangeRight(Canvas canvas) {drawText(canvas,changeTextColor,(int) (mTextStartX + ((1-mProgress )* mTextWidth)),mTextWidth + mTextStartX);}/*** 当绘制位置为DIRECTION.RIGHT的时候* 绘制未变换的部分,也就是黑色部分* 裁剪的起始位置为:mTextStartX。* 终止位置为:mTextStartX + ((1-mProgress )* mTextWidth)*/private void drawOriginRight(Canvas canvas) {drawText(canvas, originTextColor, mTextStartX, (int) (mTextStartX + ((1 - mProgress) * mTextWidth)));}private void drawOriginLeft(Canvas canvas) {drawText(canvas, originTextColor, (int) (mTextStartX + (mProgress * mTextWidth)), mTextWidth + mTextStartX);}private void drawChangeLeft(Canvas canvas) {drawText(canvas, changeTextColor, mTextStartX, (int) (mTextStartX + (mProgress * mTextWidth)));//drawText(canvas,changeTextColor, mTextStartX, (int) (mTextStartX + (mProgress * mTe)));}/*** 从startX裁剪到endX范围绘制文本*/private void drawText(Canvas canvas,int color, int startX, int endX) {mPaint.setColor(color);canvas.save(Canvas.CLIP_SAVE_FLAG);canvas.clipRect(startX, 0, endX, getMeasuredHeight());/*** 绘制文本的y坐标,看不懂的话可以看我师傅的神作,博客有给出链接*/int baseY= (int) (getMeasuredHeight()/2+(mPaint.getFontMetrics().bottom-mPaint.getFontMetrics().top)/2-mPaint.getFontMetrics().bottom);canvas.drawText(mText,mTextStartX,baseY,mPaint);canvas.restore();}public void startAnima(){ValueAnimator animator=ValueAnimator.ofFloat(0,1.0f);animator.setDuration(1500);animator.setInterpolator(new AccelerateDecelerateInterpolator());animator.setRepeatMode(ValueAnimator.RESTART);animator.setRepeatCount(ValueAnimator.INFINITE);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (float) animation.getAnimatedValue();postInvalidate();}});animator.start();}/*** 枚举类,变换颜色的方向*/public enum DIRECTION{LEFT,RIGHT;}}

实现变色TextView及ViewPager指示器(原来可以这么简单)相关推荐

  1. Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/44098729,本文出自: [张鸿洋的博客] 1.概述 本篇博客的产生呢,是因为 ...

  2. Android_字体变色,viewpager指示器

    简介 本篇是来自鸿洋_大神的Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器这篇博客,刚开始看时觉得不是很好理解,现在自己减去了他的一些代码,自己写的一个,也实现了同样的效果, ...

  3. Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 转载请标 ...

  4. Android MagicIndicator系列之一 —— 使用MagicIndicator打造千变万化的ViewPager指示器...

    说到 ViewPager 指示器,想必大家都不陌生,绝大部分应用中都有这个.使用频率非常之高.但系统对它的支持并不好,自带的 PagerTabStrip 和 PagerTitleStrip 太弱,很难 ...

  5. 打造炫酷通用的ViewPager指示器 Adapter模式适配所有 1

    ###1.概述 上一期我们已经写了一篇 打造炫酷通用的ViewPager指示器 - 玩转字体变色 可是这种效果虽然绚烂可以装装A和C之间,但是在实际的大多数效果中并不常见,只是在内涵段子中有这个效果而 ...

  6. Android自定义view之ViewPager指示器——2

    Android自定义view之ViewPager指示器--2 上一篇<Android自定义view之ViewPager指示器--1>中我们一起写了测量和布局的流程.本篇我们继续讲解事件分发 ...

  7. Android自定义view之ViewPager指示器——1

    Android自定义view之ViewPager指示器--1 在上两篇文章<Android自定义view之measure.layout.draw三大流程>以及<Android自定义v ...

  8. Android MagicIndicator系列之一 —— 使用MagicIndicator打造千变万化的ViewPager指示器

    说到 ViewPager 指示器,想必大家都不陌生,绝大部分应用中都有这个.使用频率非常之高.但系统对它的支持并不好,自带的 PagerTabStrip 和 PagerTitleStrip 太弱,很难 ...

  9. 今日头条android自适应,Android应用中仿今日头条App制作ViewPager指示器

    一.概述顶部ViewPager指示器的字体变色,该效果图是这样的: 大概是今天头条的app,神奇的地方就在于,切换ViewPager页面的时候,顶部指示器改成了字体颜色的变化,个人觉得还是不错的. 那 ...

最新文章

  1. windows下kafka源码阅读环境搭建
  2. 1.MySQL目录结构
  3. 【 Grey Hack 】万金油脚本:原地提权工具
  4. python中装饰器的参数与返回值
  5. 为vc工程添加Unicode Debug和Unicode Release
  6. win10 快速访问存在 2345Downloads 删除解决方案
  7. 【廖雪峰官方网站/Java教程】函数式编程
  8. 区块链浏览器_带你走进Filecoin区块链浏览器filscout.io
  9. GF1_WFV(高分一号宽幅)GF6_WFV(高分六号宽幅)GF4(高分四号)CB04(中巴04星)免费下载方式简介
  10. 声明一个长方形类,属性有长和宽;操作有赋值、计算长方形的周长和面积、输出信息等,要求定义构造函数(缺省值为10)和析构函数。
  11. [IC]浅谈嵌入式MCU软件开发之中断优先级与中断嵌套
  12. 便宜好用积分兑换商城系统必须具备这些功能
  13. 数据化运营需要的四个层次
  14. 如何在对方不知情的情况下定位微信好友
  15. 在Linux中安装JKD(详细教学)
  16. 推荐系统的常用算法,选择,漫谈,推荐系统开源软件汇总
  17. FFmpeg 添加 提取mkv视频字幕
  18. 山东大学单片机原理与应用实验 3.7LCD 1602显示实验
  19. 音乐网站设计(从设计到结束)
  20. Android React Native使用原生UI组件

热门文章

  1. Docker容器运行GUI程序的方法(直接进入Docker容器运行或通过SSH连接Docker容器运行)
  2. 企业高性能缓存----varnish
  3. 如何使用netstat命令辨别DDOS入侵
  4. Pandas API参考
  5. Kyan网络监控设备账号密码泄露漏洞
  6. 按文件名批量分类文件到文件夹
  7. 生日祝福小程序_手边小程序新年祝福插件正式上线
  8. 2023,本命年向阳而生
  9. 网络打印机计算机服务,如何把局域网中的所有计算机及打印机设置共享?
  10. backgroundLinearGradient线性渐变制作折角效果