动画效果及实现:可以参考 https://github.com/facebook/shimmer-android
实现思路一:AnimatorSet
1 、需要两个ImageView,用来滚动,可以自由控制颜色;
2、用ObjectAnimator给这两个imageView添加动画;
3、利用AnimatorSet先后顺序组合这两个动画;
4、为AnimatorSet添加一个AnimatorListener监听器,当动画结束时,立刻再次启动该动画;
5、在结束动画时,记者要销毁ObjectAnimator、AnimatorSet对象;
6、在监听器中利用weakReference(弱引用)来保存animatorSet,达到及时释放内存的效果。
缺点:由于动画是无限循环的,则animator.start()方法就会无限地被调用,这样就会造成stackOverFlow,即方法栈溢出。
解决方法:在监听器中利用handler把animator.start()的消息放到消息队列中,等待执行,如下:
private static class InternalAnimatorSetListener implements Animator.AnimatorListener {
//用于保存该动画的AnimatorSet对象,用于当该动画结束时,再次启动该动画
private WeakReference<AnimatorSet> weakReference;
//处理animator.start()的消息
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: {
try {
if (weakReference != null && weakReference.get() != null) {
AnimatorSet animatorSet = weakReference.get();
if (animatorSet != null) {
animatorSet.start();
}
}
} catch (Throwable e) {
e.printStackTrace();
}
break;
}
}
}
};
public InternalAnimatorSetListener(AnimatorSet animatorSet) {
weakReference = new WeakReference<>(animatorSet);
}
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
//发送消息,obtainMessage是从消息池中拿message,不会new
handler.obtainMessage(1).sendToTarget();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
}
备注:如果想控制两个ImageView的始末位置,可以在他们的外层加一层RelativeLayout,通过定位RelativeLayout来控制imageview滚动的范围。
实现思路二:LinearGradient
1、线性渲染:LinearGradient
2、继承TextView ,重写其onDraw方法
代码如下:
public class CustomTextView extends TextView {
protected WeakReference<Context> contextWeakReference;
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
private Paint mPaint;
private int mViewWidth = 0;
private int mTranslate = 0;
private boolean mAnimating = true;
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.contextWeakReference = new WeakReference<>(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mViewWidth = getMeasuredWidth();
if (mViewWidth > 0) {
mPaint = getPaint();
mLinearGradient = new LinearGradient(-80, 0, 0, 0,
new int[]{0xffffffff, 0xff000000, 0xffffffff},
new float[]{0, 0.5f, 1f}, Shader.TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
mGradientMatrix = new Matrix();
}
if (mAnimating && mGradientMatrix != null) {
mTranslate += mViewWidth/10;
if (mTranslate > mViewWidth+80) {
mTranslate = 0;
}
mGradientMatrix.setTranslate(mTranslate, 0);
mLinearGradient.setLocalMatrix(mGradientMatrix);
postInvalidateDelayed(40);
}
}
}
缺点:如果textView中显示表情,就无法实现颜色条滚动的效果了,这个也许能实现,我暂时还没找到方法。