android文字闪动效果

原本faceBook早就有类似强大效果。文中也是参考faceBook和网上资料,改编的轻量级工具。
效果如下:
android文字闪动效果_第1张图片
使用及其简单:

EditText et = (EditText) findViewById(R.id.et);
        ShimmerHelper helper2 = new ShimmerHelper(et, et.getPaint());
        helper2.setDuration(3000);
        helper2.setMode(Shader.TileMode.REPEAT);
        helper2.setColors(Color.parseColor("#ff00ff"), Color.parseColor("#00ffff"));
        helper2.start();

原理和实现:
在绘制view的时候,我们为了使其有渐变效果,一般就加一个shader。Shader的官方解释如下:
* Shader is the based class for objects that return horizontal spans of colors
* during drawing. A subclass of Shader is installed in a Paint calling
* paint.setShader(shader). After that any object (other than a bitmap) that is
* drawn with that paint will get its color(s) from the shader.
可以看到效果图中本就是一个水平方向上的颜色渐变,因此可以通过实时改变shader的覆盖区域来实现。

用代码实现非常简单,核心方法就一个:

public void start() {
        mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                init(mView);
                ObjectAnimator animator = ObjectAnimator.ofFloat(mView, "n", 0f, 0.5f, 1f);
                animator.setDuration(mDuration);
                animator.setRepeatCount(mRepeatCount);
                animator.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        start();
                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {

                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {
                        start();
                    }

                    private void start() {
                        if (mAnimating && mGradientMatrix != null) {
                        //每次shader的变化长度为10个单位长度
                            mTranslate += mViewWidth / 10;
                            if (mTranslate > 2 * mViewWidth) {
                               // 移动了整个View的距离后 回到原位
                               mTranslate = -mViewWidth; 
                            }

        //shader的移动其实是其对应的矩阵的变化
                                             mGradientMatrix.setTranslate(mTranslate, 0);

      //将实时变化的矩阵作用到shader上   
                               mLinearGradient.setLocalMatrix(mGradientMatrix);

                        }
                        mView.postInvalidate();
                    }
                });
                animator.start();
            }
        });


    }
 private void init(View v) {
        if (mViewWidth == 0) {
            mViewWidth = v.getMeasuredWidth();
            if (mViewWidth > 0) {
            //LinearGradient继承至Shader
                mLinearGradient = new LinearGradient(-mViewWidth, 0, 0, 0,
                        mColors,
                        new float[]{0, 0.5f, 1}, mMode);
                        //将shader作用到目标view的画笔上
                mPaint.setShader(mLinearGradient);
                mGradientMatrix = new Matrix();
            }
        }
    }

这里有几点需要注意:
1、 闪动过程需要获取目标view的宽度,而一般 我们会在onCreate或者onResume里面去进行方法start()的调用。为了能正常获取到view的真实宽度,需要在onGlobalLayout里面进行获取,这也是为什么一开始需要getViewTreeObserver().addOnGlobalLayoutListener的原因
2 、在onGlobalLayout里面有一个属性动画 ObjectAnimator animator = ObjectAnimator.ofFloat(mView, “n”, 0f, 0.5f, 1f);
这里的属性“n”是一个虚属性(就是不存在的意思)。我们设置这个属性动画的目的并不是为了真正改变view的某个属性,我们只是想在动画的周期函数里面自行改变shader的覆盖长度而已。

局限性:
只能使用在能获取画笔的目标view上(view.getPaint()),例如TextView,Button,EditText等。

代码下载:
https://github.com/killer8000/ShimmerHelper/

你可能感兴趣的:(android开发)