Android 仿QQ控件变色的EditText/TextView
来源:互联网 发布:php页游源码 编辑:程序博客网 时间:2024/06/06 06:42
本人纯属博客小白,不会使用 Markdown 来编写博客,Android也才入门,可能实现起来存在缺陷,各位看官将就着看,一起交流。
最近QQ空间添加了一个新的功能,说说可以自动变色,看起来还不错的样子,于是打算模仿看看。
它变色有两种形式,一种是整体颜色渐变;另一种是线性渐变,也就是文字的头尾颜色发生变化
现在先说第一种,整体的颜色渐变。(线性渐变使用LinearGradient线性渲染实现,感兴趣可以自己去试试)
编程先说思路:
1.既然是类似EditText/TextView,那肯定要画出用户指定的文字
2.既然要颜色渐变,那肯定是不断改变画笔的颜色
如果只是想模仿QQ空间的效果。后面有更简单的方法,前面先说最初的思路,自定义程度也是最高的。
首先,先在自定义view里面开放方法让用户设置需要显示的文字,同时在onDraw里面画出来就行了,大致代码如下:
public void setText(String text){ content=text; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); canvas.drawText(content,w,h,mPaint); canvas.restore(); }
第一步,非常简单是不是,但是问题来了,万一用户没有调用setText,那么content就是null,会报空指针异常。那么解决方法有两个。
一个是初始化content="";一个实在drawText前加判断:
if (content==null){ return; }当然,除了这个之外你们还可以开放其他方法来设置字体、字体大小、字体显示位置等。也可以自定义attr,直接在XML设置就不用使用java代码设置了。
第二步无非是设置颜色,当然也需要开放方法或者定义attr。既然是渐变,我们肯定需要两种颜色。
public void setTextTransitionColor(int startColor,int endColor){ this.startColor=startColor; this.endColor=endColor; }
起初我是这么想的,在这两种颜色中变化,直接一个属性动画不就行了么?变化范围就在这两种颜色之间就行了。然后我就这么写了
private void startTransition() { ValueAnimator colorAnim =ValueAnimator.ofInt(startColor,endColor); colorAnim.setDuration(repeatTime); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mPaint.setColor((Integer) animation.getAnimatedValue()); invalidate(); } }); colorAnim.start(); isAnim=true; }
然后...那颜色变化简直就是闪瞎眼啊,就算装有钛合金狗眼也瞎了,根本不是那种缓和的渐变效果,而是快速变化!举个例子,你设置开始颜色值0X000000,结束颜色值0xFFFFFF,那么值就会从0X000000变化到0xFFFFFF,在短短一两秒内,什么颜色都出现了,并不是我们需要的效果。
那么怎么样才能实现渐变?以下就是最主要的颜色渐变算法了。
既然这样子不行,我们仔细想想,QQ空间那颜色的变化的感觉只在设定的两种颜色中变化,就像是现实中把两种颜色按不同的比例进行调和,从1:0--0:1,不就是这种效果么
?那么我们也来“调和”一下好了。
既然要调和,我们用什么来调整两种颜色比例呢?没错,就是透明度。把两种颜色覆盖在一起,通过不断调整深度值,不就达到了我们的效果了么?
首先需要先把用户设定的颜色分解成ARGB,然后通过调整深度值,再把两种颜色相加,就完成了调和的效果,深度从0%-100%,也就是0-->1:
private void startTransition() { ValueAnimator colorAnim =ValueAnimator.ofFloat(0,1); colorAnim.setDuration(repeatTime); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.setRepeatCount(ValueAnimator.INFINITE); //颜色分解 sa=Color.alpha(startColor); sr=Color.red(startColor); sg=Color.green(startColor); sb=Color.blue(startColor); ea=Color.alpha(endColor); er=Color.red(endColor); eg=Color.green(endColor); eb=Color.blue(endColor); colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //随着时间的变化开始颜色的深度 1-->0 float sv = (float)animation.getAnimatedValue(); ////随着时间的变化结束颜色的深度 0-->1 float ev= 1f-(float)animation.getAnimatedValue(); //就是调用 mPaint.setColor(Color.argb(a,r,g,b)),里面的a,r,g,b是调和后的颜色 //这里需要分别计算颜色深度在想加 mPaint.setColor(Color.argb((int)(ea*ev+sa*sv),(int)(sr*sv+er*ev),(int)(sg*sv+eg*ev),(int)(sb*sv+eb*ev))); invalidate(); } }); colorAnim.start(); isAnim=true; }
这样就实现了我们想要的效果,效果图:
大家还需要注意的是这两行代码:
colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.setRepeatCount(ValueAnimator.INFINITE);
要让颜色一直渐变下去,需要设置动画重复次数为无限次,
这样还不行,例如你设置的颜色是红,绿 那么变化就是 红-->绿 立马变化红,在重复红-->绿 也就是从绿到红不是渐变的,看起来十分突兀。所以设置重复Mode为反转即可,就是colorAnim.setRepeatMode(ValueAnimator.REVERSE);
那什么时候开启这个动画呢?当然是用户设置颜色之后了,你在用户设定颜色的方法里面电影这个动画的方法就行了:
public void setTextTransitionColor(int startColor,int endColor){ this.startColor=startColor; this.endColor=endColor; startTransition(); }
那么简单的颜色渐变效果就有了,我之所以说这个自定义程度最高是因为这个View是继承View的,你可以进行其他额外的拓展。
如果你想只是实现QQ空间的效果,并且保留有原生EditText/TextView的属性和方法,更简单的方法就是直接继承EditText/TextView,然后根据我们上面的颜色调和的方法,调用他们的setTextColor就行了,这里以EditText为例:
public class ColorEditText extends AppCompatEditText { private int repeatTime; private int sa,sr,sg,sb,ea,er,eg,eb; public ColorEditText(Context context) { super(context); } public ColorEditText(Context context, AttributeSet attrs) { super(context, attrs); } public ColorEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setTextTransitionColor(int startColor,int endColor){ sa= Color.alpha(startColor); sr=Color.red(startColor); sg=Color.green(startColor); sb=Color.blue(startColor); ea=Color.alpha(endColor); er=Color.red(endColor); eg=Color.green(endColor); eb=Color.blue(endColor); startTransition(); } public void setRepeatTime(int repeatTime) { this.repeatTime = repeatTime; } private void startTransition() { ValueAnimator colorAnim =ValueAnimator.ofFloat(0,1); colorAnim.setDuration(repeatTime); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float sv = (float)animation.getAnimatedValue(); float ev= 1f-(float)animation.getAnimatedValue(); setTextColor(Color.argb((int)(ea*ev+sa*sv),(int)(sr*sv+er*ev),(int)(sg*sv+eg*ev),(int)(sb*sv+eb*ev))); invalidate(); } }); colorAnim.start(); }}
非常的简单是不是,也可以不用自定义直接在activity实现这个逻辑也行..
大概实现方法就这样的,预览图暂时没有,经过我测试已经完全可以模仿QQ空间的效果了,大家直接去QQ空间看预览图吧..
至于线性变化,有空再说...也不难,比这个还简单,大家感兴趣自己了解一下LinearGradient线性渲染就会了。
至于demo我在github上有,但是没有任何注释,没什么参考价值,大家有问题直接在下方评论就好了。
到此。
- Android 仿QQ控件变色的EditText/TextView
- android textview或者edittext显示像QQ那样的图片
- Android控件属性 (TextView 、EditText )
- Android常见的几个控件(TextView,EditText,Button)
- Android基本常用控件的介绍TextView EditText Button Menu
- Android的常见控件(TextView、EditText、Button、Menu)使用
- Android学习-常见的UI控件 TextView、EditText和ImageView
- Android系统控件TextView与EditText
- Android基础控件之TextView与EditText
- Android之TextView、EditText控件显示表情图片
- Android控件复习之TextView与EditText
- Android常用控件(TextView-EditText-Shape-Selector)
- Android控件中TextView及EditText详解
- 仿QQ列表--Android控件ExpandableListView的使用
- android 的TextView与EditText
- Android用户界面基础之TextView控件,EditText控件,Button控件的学习
- Android 自定义日期控件 (仿QQ,IOS7)
- Android 自定义日期控件 (仿QQ,IOS7)
- Android内存优化之OOM
- 图像增强-模糊集方法
- Leetcode Climbing Stairs
- day06 缓冲区、数组
- Websphere 6.0 设置垃圾回收机制 出现 java launcher 已停止工作 产生 错误代码:40000015
- Android 仿QQ控件变色的EditText/TextView
- mysql进程-状态-在线修改参数(在增量备份情况下)
- UML类图几种关系的总结
- 6.20作业:static,final,继承和方法覆盖
- mydumper备份原理和使用方法
- React/Redux应用使用Async/Await
- BZOJ 3265 志愿者招募(BZOJ 1061)加强版 && BZOJ 3112 [Zjoi2013]防守战线 单纯形
- 日语语法整理三
- js前端进行同一域名或不同域名下两个页面跨域通信