Android动画之Animator
来源:互联网 发布:淘宝导航制作 编辑:程序博客网 时间:2024/05/22 10:49
Animator动画可以用xml文件描述和java程序实现。先上一张Animator的官方结构图
xml实现,新建描述文件res/animator/animator_set1.xml,注意文件放在animator目录下面。
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="2000" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="alpha" android:repeatCount="1" android:repeatMode="restart" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /> <objectAnimator android:duration="3000" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="scaleX" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType" /></set>
属性解释:
ordering:有两个值sequentially和together,前者表示顺序播放后者是同时播
interpolator:值插器,简单来说就是控制动画播放速率的(可以自行查找下)
propertyName:此动画要作用的View的属性名称,一般有getter和setter方法的的属性都可以使用
repeatCount:动画重复次数,注意第一次播放不算是重复,所以如果想动画播放两次,值为1就行
repeatMode:重复的模式,两个值restart和reverse,reverse是指按原动画倒着来一次,restart自然就是重新播一遍动画
valueFrom:propertyName属性的起始值,valueTo就是结束值,valueType属性值的数值类型
程序中使用:
AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animator_set1); animatorSet.setTarget(imageView); animatorSet.start();
用java当然也可以达到上面效果,AnimatorSet提供了几个方法playSequentially()、playTogether()都可以接收ObjecAnimator的Array或者List实现Animator的顺序或者同时播放:
ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1); animatorA.setDuration(2000); ObjectAnimator animatorB = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1.0f); animatorB.setDuration(3000); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playSequentially(animatorA, animatorB); animatorSet.start();或者
ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1); animatorA.setDuration(2000); ObjectAnimator animatorB = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1.0f); animatorB.setDuration(3000); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(animatorA).before(animatorB); animatorSet.start();这样animatorA播完以后播animatorB,这时候如果有需要和animatorA同时播放的的animatorC,则可以这样animatorSet.play(animatorA).with(animatorA).before(animatorB),with表示和他前面离with最近的动作一起执行,此时就是animatorA。其实看源码就知道playTogether的内部是实现就是依靠多次with调用来做的。
另一种稍微复杂一点的描述:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="2000" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="alpha" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /> <objectAnimator android:duration="5000" android:interpolator="@android:anim/accelerate_decelerate_interpolator"> <propertyValuesHolder android:propertyName="scaleX" android:valueFrom="0.5" android:valueTo="1.0" android:valueType="floatType" /> <propertyValuesHolder android:propertyName="x"> <keyframe android:fraction="0.3" android:value="600" /> <keyframe android:fraction="1" android:value="350" /> </propertyValuesHolder> <propertyValuesHolder android:propertyName="y"> <keyframe android:fraction="0.3" android:value="200" /> <keyframe android:fraction="1" android:value="300" /> </propertyValuesHolder> </objectAnimator></set>
用keyframe完成一个运行轨迹,使用这种方法的时候keyframe的上层标签objectAnimator不要再描述某些属性,如android:propertyName="scaleX",不然keyframe将失效。
keyframe的其他属性没什么特别,说下fraction属性,其取值0<= fraction <=1,动画时间是fraction的作用对象,0表示起始时间1表示结束时间,中间小数是动画时间的百分比。运行过程中也可以用interpolator设置速率。同上简单的java引入就可以使用
用java实现:
ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1); animatorA.setDuration(2000); PropertyValuesHolder propertyValuesHolder0 = PropertyValuesHolder.ofFloat("scaleX", 0.5f, 1.0f); Keyframe keyframe1 = Keyframe.ofFloat(0.3f, 600); Keyframe keyframe2 = Keyframe.ofFloat(1f, 350); PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofKeyframe("x", keyframe1, keyframe2); Keyframe keyframe3 = Keyframe.ofFloat(0.3f, 200); Keyframe keyframe4 = Keyframe.ofFloat(1f, 300); PropertyValuesHolder propertyValuesHolder2 = PropertyValuesHolder.ofKeyframe("y", keyframe3, keyframe4); ObjectAnimator animatorB = ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder0, propertyValuesHolder1, propertyValuesHolder2); animatorB.setDuration(5000); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(animatorA).before(animatorB); animatorSet.start();ObjectAnimator和ProperyValuesHolder都有ofFloat和ofInt不同的是ObjectAnimator比PropertyValuesHolder都多了一个作用对象也就是参数中的target。注意PropertyValuesHolder中只有一个Keyframe会出错的至少有两个才行。从以上这些例子中不难发现ObjectAnimator中的PropertyValuesHolder都是同时执行的动画。
使用ofObject做动画的时候要指明Evaluator,否则系统不知道这个Object是什么该怎么去计算,如PropertryValuesHolder的ofObject函数也能获得PropertryValuesHolder的实例,使用的时候要指明Evaluator。
TypeEvaluator<Float> evaluator = new TypeEvaluator<Float>() { float startInt; @Override public Float evaluate(float fraction, Float startValue, Float endValue) { startInt = startValue;// fraction是当前运动时间占总动画时间的比值 return startInt + fraction * (endValue - startValue); } }; ObjectAnimator animatorA = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1); animatorA.setDuration(2000); ObjectAnimator animatorB = ObjectAnimator.ofFloat(imageView, "scaleX", 0.5f, 1.0f); animatorB.setDuration(3000); PropertyValuesHolder propertyValuesHolder0 = PropertyValuesHolder.ofObject("y", evaluator, imgY, 300f); ValueAnimator valueAnimator0 = ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder0); valueAnimator0.setDuration(3000); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(animatorA).with(animatorB).before(valueAnimator0); animatorSet.start();
代码中关于ValueAnimator的部分也可以用以下代替达到上面同样的效果:
ValueAnimator valueAnimator0 = new ValueAnimator(); valueAnimator0.setTarget(imageView); valueAnimator0.setObjectValues(imgY, 300f); valueAnimator0.setEvaluator(evaluator); valueAnimator0.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float y = (float) animation.getAnimatedValue(); imageView.setY(y); } });
AnimatorUpdateListener是对动画的值更新进行监听,我们能在回调函数中获取到某属性当前的值,单一属性值的改变不用指定属性名称如上。
还有一个简单的动画类,ViewPropertyAnimator,使用很简单,简单的动画可以用它ViewPropertyAnimator propertyAnimator = imageView.animate(); propertyAnimator.translationXBy(100) .setDuration(1000) .start();
Animator的监听器添加addListener():
new AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} @Override public void onAnimationEnd(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} }
// 对AnimatorListener的空实现,并且多出两个 new AnimatorListenerAdapter() { @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationEnd(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationPause(Animator animation) {} @Override public void onAnimationResume(Animator animation) {} }
- Android动画之Animator
- Android动画之Animator
- Android之属性动画Animator
- Android之Animator属性动画
- Android 动画之属性动画(Animator)
- Android动画之(Property Animator(属性动画))
- 【Android - 基础】之Animator属性动画
- android animator 动画
- android animator 动画
- android动画 -- Property Animator
- android属性动画animator
- Android属性动画(Animator)
- android 简单动画Animator
- Android动画之属性动画Animator详解(卫星菜单)
- Android开发之旅一简单的Animator动画使用
- Android开发之用Animator实现动画效果
- Android Animator(Android动画)
- Android Animator(Android动画)
- 解释器vs编译器 && C,java,python编译过程对比
- 文章标题 CSU 1856: Sokoban(模拟)
- 微信支付
- C语言的起源
- 使用Dockerfile制作Docker镜像
- Android动画之Animator
- device_create、class_create、driver_register函数
- 设置Intellij idea和maven,支持lambda表达式
- 立方体模型
- sublime常用快捷键
- 部署Node.js项目到阿里云CentOS 7.x(Linux)
- 事件处理及解决事件冲突
- unity dropdown 界面设计
- 类图中的依赖、关联、聚集、构成、泛化、实现关系