优雅地使用drawable做动画

优雅地使用自定义drawable做动画

效果

录屏效果

下载

下载地址

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值