ShimmerTextView
本文来自网易云社区
作者:孙有军
产品中有一个需求,要求TextView的文字有一个高亮的效果,高亮的同时有跑马灯效果!
本来想在网上找一个现成的用用,比如Facebook出的Shimmer,还有很多,但是都感觉代码太多,因此撸了一个简单版的,talk is cheap,show me you code。
实现
我们知道TextView的文字的颜色是由Paint根据Color控制的,我们可以设置Paint的Shader来实现该效果,这样在TextView绘制的时候Paint会从对应的Shader获取color来实现绘制。既然TextView要高亮,说明文字颜色不一致,这里我们可以设置一线性渐变shader,这样就可以设置不同部分的文字不同颜色。至于跑马灯那就一直水平改变Shader就可以实现。
属性定义
虽然是简单的,还是要通用,比如颜色可以自定义,方向可以设置,是否自动开始,这里我们先定义几个属性:
<declare-styleable name="ShimmerTextView">
<attr name="auto_start" format="boolean"></attr>
<attr name="start_color" format="reference|color"></attr>
<attr name="end_color" format="reference|color"></attr>
<attr name="direction" format="boolean"></attr></declare-styleable>
这里我们分别控制了是否自动开始,开始颜色,结束颜色,方向
代码实现
这里我们实现一个继承自AppCompatTextView的自定义TextView。
public class ShimmerTextView extends android.support.v7.widget.AppCompatTextView {
public static final int OFFSET_ONE_TIME = 15;
private Paint paint;
private LinearGradient gradient;
private Matrix matrix;
private int w, h;
private boolean horizontal;
private boolean autoStart;
private int startColor;
private int endColor;
private static final int DEFAULT_START_COLOR = 0xFFFF50ED;
private static final int DEFAULT_END_COLOR = 0xFF3455FF;
private float offset = 0;
private ValueAnimator animator;
public ShimmerTextView(Context context) {
super(context);
init(context, null);
}
public ShimmerTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ShimmerTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
paint = getPaint();
matrix = new Matrix();
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ShimmerTextView);
autoStart = array.getBoolean(R.styleable.ShimmerTextView_auto_start, false);
startColor = array.getColor(R.styleable.ShimmerTextView_start_color, DEFAULT_START_COLOR);
endColor = array.getColor(R.styleable.ShimmerTextView_end_color, DEFAULT_END_COLOR);
horizontal = array.getBoolean(R.styleable.ShimmerTextView_direction, true);
array.recycle();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.w = w;
this.h = h;
setGradient();
}
private void setGradient() {
if (horizontal) {
gradient = new LinearGradient(0, 0, w, 0, new int[]{startColor, endColor, startColor}, new float[]{0,
0.5f, 1.0f}, Shader.TileMode.CLAMP);
} else {
gradient = new LinearGradient(0, 0, 0, h, new int[]{startColor, endColor, startColor}, new float[]{0,
0.5f, 1.0f}, Shader.TileMode.CLAMP);
}
paint.setShader(gradient);
invalidate();
if (autoStart) {
play();
}
}
public void play() {
ValueAnimator animator = getAnimator();
if (animator.isRunning()) {
return;
}
animator.start();
}
@NonNull
private ValueAnimator getAnimator() {
if (animator == null) {
animator = ValueAnimator.ofFloat(0.0f, 1.0f);
animator.setDuration(500);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
offset += OFFSET_ONE_TIME;
if (horizontal) {
if (offset > w) {
offset = -w;
}
} else {
if (offset > h) {
offset -= h;
}
}
invalidate();
}
});
}
return animator;
}
public void stop() {
if (animator != null) {
animator.cancel();
}
}
public void reset() {
if (animator != null) {
animator.cancel();
animator = null;
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
reset();
}
@Override
protected void onDraw(Canvas canvas) {
matrix.setTranslate(offset, 0);
gradient.setLocalMatrix(matrix);
super.onDraw(canvas);
}
}
上面的代码主要先解析了自定义属性,之后设置了一个线性渐变来改变文字的颜色,之后采用了ValueAnimator来水平移动线性渐变,同时重新绘制内容。
ValueAnimator 我们设置了一直重复动画,ValueAnimator就是一个数值发生器,其实可以用Handler与post来实现相同的效果。只要按一定速率改变线性渐变就可以
需要注意的是当距离大于整个View的宽度或者高度时,需要重新开始
效果
最后我们在界面中使用该控件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.demo.example.activity.ShimmerViewActivity"> <com.demo.example.widget.ShimmerTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:gravity="center" android:text="我爱北京天安门" android:textSize="25sp" app:auto_start="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.502" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.148"/> </android.support.constraint.ConstraintLayout>
在Activity中设置该控件,运行效果。
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区
相关文章:
【推荐】 abtest-system后台系统设计与搭建
【推荐】 责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
【推荐】 4月第3周业务风控关注 | 文化部再次审查直播和游戏产品,已下架4939款直播应用
ShimmerTextView的更多相关文章
- 更强的微光闪烁效果--第三方开源--Shimmer-android
Shimmer-android在github上的项目主页是:https://github.com/RomainPiel/Shimmer-android Shimmer-android干脆在Androi ...
- Android Tools 开发工具库开源项目总结
在Android开发中,我们不免会遇到使用一些工具库来简化我们的工具代码的编写,以下是本人之前star的开源项目,供大家参考: 一.android_testsuite 项目地址:https://git ...
- 模拟QQ分组(具有伸缩功能) (添加开源框架的光闪烁效果)SimpleExpandableListAdapter 适配器的用法,并且可添加组及其组内数据。
package com.lixu.qqfenzu; import java.util.ArrayList; import java.util.HashMap; import java.util.Lis ...
- 认识一下Kotlin语言,Android平台的Swift
今天在CSDN首页偶然看到一个贴子JetBrains正式公布Kotlin 1.0:JVM和Android上更好用的语言 看完后,感觉Kotlin语法非常简洁,有一系列动态语言的特点,Lambda表达式 ...
- LinearGradient线型渐变效果
public LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, TileM ...
随机推荐
- python代码是解释型语言,为什么还有编译过程?
Python 代码在运行前,会先编译(翻译)成中间代码,每个 .py 文件将被换转成 .pyc 文件,.pyc 就是一种字节码文件,它是与平台无关的中间代码,不管你放在 Windows 还是 Linu ...
- 【CSS单位】px、em、rem
1.PX为单位 在Web页面初期制作中,我们都是使用“px”来设置我们的文本,因为他比较稳定和精确.但是这种方法存在一个问题,当用户在浏览器中浏览我们制作的Web页面时,他改变了浏览器的字体大小,这时 ...
- 调节Ubuntu分辨率
列出当前支持的分辨率 使用 xrandr 命令新增显示模式 至此分辨率更改完成 重启后会失效 在 ~/.profile 最末尾添加修改分辨率的命令
- VBA与宏
VBA与宏 ====== 刚开始的内容听起来很枯燥,请大家不要分心,耐着性子看下去,兴趣总是慢慢积累的. ----------------------------------------------- ...
- P2894 [USACO08FEB]酒店Hotel
P2894 [USACO08FEB]酒店Hotel 简单的线段树维护区间信息. 维护三个值,一个是从左端点能拓展的长度,一个是从右端点能脱产的的长度.另一个是整个区间内的最大连续零一长度. 记录这三个 ...
- 【UVA11806 Cheerleaders】 题解
题目链接:https://www.luogu.org/problemnew/show/UVA11806 容斥原理+组合数 正着找合♂fa的不好找,那就用总方案数-不合♂fa的 #include < ...
- HDU 1014 Uniform Generator(模拟和公式)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1014 Uniform Generator Time Limit: 2000/1000 MS (Java ...
- PCB 布线 注意哪些问题记录
1.过孔不能打在焊盘上 ,这样 焊接的时候 会有焊锡 溢出导致 短路. 2.焊盘的线引出时应该从中间引出,不应该从角落引出 3.当有较粗的电源线连接在元器件上时,最好是 有一根小线连接在元器件上,回流 ...
- C++备忘知识整理
一.设置字体颜色 C++控制台程序运行时输出框默认的文字颜色是白色,所以我常称其输出框为黑白框.但是这个文字样式不是固定不变的,是可以改变颜色的字体的.方法有两种: 1.设置输出框的框体属性.在运行时 ...
- 小程序内嵌H5——判断小程序环境的坑
现在各种小程序风靡,这边H5的需求还没有搞定,产品又要求做小程序版本,做可以,关键是618前上线,我-- whatever,618要做推广,日期订了,剩下的就只能是排期,定方案,尽可能完成. 最后和产 ...