属性动画之Rx框架

前言

我们都知道,Android中有了属性动画之后,我们的动画再也不是表面功夫了,他可以实实在在的改变控件的属性.而这个改变属性的动作不断的执行就形成了动画,也就是我们属性动画的原理

关于属性动画的使用详解请移步博主的另一片博客:属性动画使用详解

库的地址为:属性动画库


下面让博主一步一步来解释 封装一个属性动画框架的重要性

使用系统属性动画实现需求

这里写图片描述

这个界面有三个按钮,xml就不分享出来了,很简单

Activity中的代码分享一下

public class MainAct extends AppCompatActivity {

    private Button bt1;
    private Button bt2;
    private Button bt3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_main);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        bt3 = (Button) findViewById(R.id.bt3);
    }

    //按钮1的点击事件
    public void click1(View v) {
    }
}

动画需求1

点击按钮1 让按钮1 旋转顺时针90°,时长为500毫秒

那么看过上面的文章的同学应该会很容易的想到以下的代码

ObjectAnimator  
    .ofFloat(v, "rotation", v.getRotation(), v.getRotation() + 90)  
    .setDuration(2000)  
    .start();

那么我们的Activity完整代码就是

public class MainAct extends AppCompatActivity {

    private Button bt1;
    private Button bt2;
    private Button bt3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_main);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        bt3 = (Button) findViewById(R.id.bt3);
    }

    //按钮1的点击事件
    public void click1(View v) {
        ObjectAnimator
                .ofFloat(v, "rotation", v.getRotation(), v.getRotation() + 90)
                .setDuration(500)
                .start();
    }

}

效果为

这里写图片描述

动画需求2

在动画1动画完毕之后,做一个从完全不透明到完全透明的动画,时长为3000毫秒
那么机智的你很容易就想到了,监听动画1结束的时候,然后做动画2,那么代码就是如下

    //按钮1的点击事件
    public void click1(final View v) {
        ObjectAnimator objectAnimator = ObjectAnimator
                .ofFloat(v, "rotation", v.getRotation(), v.getRotation() + 90)
                .setDuration(500);

        objectAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                ObjectAnimator objectAnimator = ObjectAnimator
                        .ofFloat(v, "alpha", 1,0)
                        .setDuration(3000);
                objectAnimator.start();
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

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

        objectAnimator.start();
    }

那么也完成需求了

动画需求3

接着需求2再从完全透明到完全不透明,时长为3000

这时候你就开始犯愁了,因为连着的动画越多,你的嵌套越多,尽管你把每一个动画都提取成一个方法,还是不够简洁明了的表示

这是一个使用中的弊端:对于连续的多个动画,需要写的垃圾代码太多,而且代码不够简洁明了

动画需求4

点击按钮1,让三个按钮同时转动360°,时长为1000毫秒
这对于机制的你还是一点问题都没有

刷刷写下以下代码

//按钮1的点击事件
    public void click1(final View v) {

        ValueAnimator objectAnimator = ObjectAnimator//
                .ofFloat(0,360)//
                .setDuration(1000);
        //设置更新数据的监听
        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();
                bt1.setRotation(value);
                bt2.setRotation(value);
                bt3.setRotation(value);
            }
        });

        objectAnimator.start();

    }

效果

这里写图片描述

动画需求5

基于动画4,我想要每一个按钮的动画的开始执行时间相差400毫秒一个,这就很尴尬了
你需要结合Handler分别发送几个延时的消息,然后接受到消息后分别进行动画.
这种行为在博主看来是很傻的行为,不仅写垃圾代码而且浪费时间,也不够清晰,所以这也就是链式调用的产生

Rx本身是一个是想,在每一种语言上基本都有相应的实现,然后博主就把这种是想用在了属性动画上,致力于让属性动画变得更简单

属性动画框架的使用


目前博主个人开发进度比较缓慢,目前开发的是预览版.希望广大爱好者一起参与,库:

属性动画库

下面简单介绍一下用法

需求:按钮1和按钮2同时旋转180°,时长1000

    //按钮1的点击事件
    public void click1(final View v) {

        XanimAnimator
                .from(bt1,bt2)
                .anim(1000, new XanimMaker() {
                    @Override
                    public void onAnim(Xanim anim) {
                        anim.rotate(180);
                    }
                })
                .subscribe(new OnSubscribe<View>() {
                    @Override
                    public void onNext(View view) {
                    }

                    @Override
                    public void onComplete() {
                    }

                    @Override
                    public void onError(Throwable t) {
                    }
                });

    }

这里写图片描述

我们可以看到,其实现在看不出代码量和逻辑的清晰,接下来再看

需求:按钮1和按钮2同时顺时针旋转180°,时长1000,并且结束之后和按钮3一起逆时针旋转180°

这里写图片描述

我们可以看到,我们的代码依然是保持简洁,并且每一个动画之间是连续的,你再也不需要监听前一个动画的结束来做下一个动画啦

功能不仅于此

在Anim对象中,提供了平移、缩放、旋转、透明度的四种基本的动画

anim.rotate(-180).scale(3).translate(100).toAlpha(0.8f);

需求:按钮1和按钮2同时顺时针旋转180°,时长1000,然后和按钮3一起,每一个控件动画时长间隔500毫秒,一起逆时针旋转180°

        XanimAnimator
                .from(bt1,bt2)
                .anim(1000, new XanimMaker() {
                    @Override
                    public void onAnim(Xanim anim) {
                        anim.rotate(180);
                    }
                })
                .with(bt3)
                .delayEach(500)
                .anim(1000, new XanimMaker() {
                    @Override
                    public void onAnim(Xanim anim) {
                        anim.rotate(-180);
                    }
                })
                .subscribe(new OnSubscribe<View>() {
                    @Override
                    public void onNext(View view) {

                    }

                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onError(Throwable t) {

                    }
                });

这里写图片描述

可以看到代码依然简洁明了,我相信以后这个框架会越来越成熟,希望越来越多的人来参与.
如果你想使用,见博客最下面

如何使用

详见github地址:anim库

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值