自定义的转场动画实现方式以及原理介绍

BreatheView

项目地址:arvinljw/BreatheView 

简介:自定义的转场动画实现方式以及原理介绍

更多:作者   提 Bug   

标签:

Animation-

这是一个自定义的转场动画实现方式,目前支持两种方式:

  • 圆形展开
  • 矩形展开

效果如下:

使用

引用:

在根目录级的 build.gradle 中添加

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

再在要使用的项目级的 build.gradle 中添加:

dependencies {
    compile 'com.github.arvinljw:BreatheView:v1.0.0'
}

api 介绍

1、打开界面动画

breatheView.startScaleBigger();

2、关闭界面动画

breatheView.startScaleSmaller();

3、设置背景颜色

breatheView.setBgColor(int color)

简单介绍一下,这个动画是通过绘制,使用 Xfermode 实现的,先绘制背景部分,再绘制展开的部分,展开部分和背景重叠部分就变透明,这里设置的颜色就是这个背景颜色。

4、绘制的起始点

这里要分情况,目前提供了两种方式去展开:

  • CircleBreatheView
```
circleBreatheView.setDrawPoint(Point point)
circleBreatheView.setDrawPoint(int x,int y)
```
  • RectBreatheView

      rectBreatheView.setDrawRect(Rect rect)
      rectBreatheView.setDrawRect(int left,int top,int right,int bottom)
    

    建议使用 setDrawRect 时,尽量保证水平或者垂直方向一边是占满屏幕的,因为目前没有分水平和垂直去分别计算

5、使用技巧

可参照 app 中例子的代码。

重点

启动新的界面后,在 startActivity 后边加上一句

overridePendingTransition(0, 0);

去掉系统转场动画,同理在关闭的时候,在 finish 后边也加上这一句。

6、扩展

可以自己继承 BreatheView,参照 RectBreatheView 或者 CircleBreatheView 实现自己的自定义转场动画。

原理

mMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int saveCount = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
    drawBg(canvas);
    mPaintSrc.setXfermode(mMode);
    drawBreathe(canvas);
    mPaintSrc.setXfermode(null);
    canvas.restoreToCount(saveCount);
}

如果知道 Xfermode,那么一看上边的代码应该就明白一大半了,当然这只是其中重要的一步,还有一步就是使用属性动画,改变绘制 BreatheView 部分的大小,例如

public void setScale(int scale) {
    this.mScale = scale;
    postInvalidate();
}

public int getScale() {
    return mScale;
}

protected void startScaleAnim(int start, int end) {
    final boolean isOpen = start < end;
    ObjectAnimator scale = ObjectAnimator.ofInt(this, "scale", start, end).setDuration(mDuration);
    scale.setInterpolator(new LinearInterpolator());
    scale.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationStart(Animator animation) {
            setVisibility(View.VISIBLE);
        }
        @Override
        public void onAnimationEnd(Animator animation) {
            canClose = isOpen;
            if (mAnimEndListener != null) {
                mAnimEndListener.onAnimEnd(isOpen);
            }
        }
    });
    scale.start();
}

protected void drawBg(Canvas canvas) {
    canvas.drawRect(mBgRect, mBgPaint);
}

@Override
protected void drawBreathe(Canvas canvas) {
    canvas.drawCircle(mDrawPoint.x, mDrawPoint.y, mScale, mPaintBreathe);
}

核心代码就是这些,最重要就是通过属性动画,改变绘制的 breathe 部分的大小,并在 onDraw 时使用 Xfermode 实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值