前言
我们都知道,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库