美文网首页
优雅地使用Drawable做动画

优雅地使用Drawable做动画

作者: 我是二哥呀 | 来源:发表于2018-11-28 15:40 被阅读0次

    效果

    [图片上传失败...(image-43a1a3-1543390766656)]

    下载

    下载地址

    github

    github

    实现上图动画,可以有以下几种方式

    1.布局里写三个view, 然后用一个ValueAnimator改变这三个view的height

    • 太糙了,一个loading动画,你要放三个view进去,那要是100条线的动画呢=_=||

    2.自定义一个view, 在这个view里面放一个ValueAnimator,在onDraw方法里面绘制三条线

    • 就一个loading动画,你要自定义一个view,是不是有点不够灵活,而且有点重了

    3.Lottie、SVGA等第三方动画库

    • 当这个动画面积比较大的时候,或者这个动画要放在recyclerview的item里的时候,会有性能瓶颈

    4.自定义Drawable

    • 本质有点类似阉割版的view,好处是可以直接放在ImageView里,或者作为任意一个view的background

    这篇文章重点介绍自定义drawable

    • 核心是draw方法
    @Override
        public void draw(@NonNull Canvas canvas) {
            for (int i = 0; i < 3; i++) {
                canvas.save();
                canvas.translate(mDeltaX * (1 + i), mDeltaY);
                canvas.drawLine(0, canvas.getHeight() * getFractionByIndex(i) / -4,
                        0, canvas.getHeight() / 4 * getFractionByIndex(i), mPaint);
                canvas.restore();
            }
        }
    
    • 在构造方法里创建一个ValueAnimation
    public class CustomDrawable extends Drawable implements Animatable
    
    public CustomDrawable() {
            mPaint = new Paint();
            mPaint.setColor(Color.RED);
            mPaint.setStrokeWidth(STROKE_WIDTH_PX);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mAnimator = ValueAnimator.ofFloat(0.4f, 1f).setDuration(300);
            mAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mAnimator.setRepeatMode(ValueAnimator.REVERSE);
            mAnimator.addUpdateListener(animation -> {
                mFraction = (float) animation.getAnimatedValue();
                invalidateSelf();
            });
        }
    
    • 需要重写下列方法
    @Override
        public void start() {
            if (mAnimator == null) return;
            if (mAnimator.isRunning()) return;
            mAnimator.start();
        }
    
        @Override
        public void stop() {
            if (mAnimator == null) return;
            mAnimator.cancel();
        }
    
    
        @Override
        public boolean isRunning() {
            return mAnimator != null && mAnimator.isRunning();
        }
    
        @Override
        protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            mDeltaX = bounds.width() / 4;
            mDeltaY = bounds.height() / 2;
        }
    

    tips

    别忘了释放动画,以免造成内存泄漏

    @Override
        protected void onResume() {
            super.onResume();
            mDrawable.start();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            mDrawable.stop();
        }
    

    Author

    戴书文 - 153513741@qq.com

    相关文章

      网友评论

          本文标题:优雅地使用Drawable做动画

          本文链接:https://www.haomeiwen.com/subject/ctnaqqtx.html