属性动画 Animator
传统动画Animation 缺点 不断重绘onDraw()方法,绑定的事情点击区域仍在原来位置
查看全部
多个ObjectAnimator 动画 是同时异步执行的,并不是依次执行。
也可以使用PropertyValueHolder
PropertyValueHolder p = PropertyValueHolder.ofFloat("rotation. 0. 360f");
ObjectAnimator.ofPropertyValuesHolder(view, p1);
比创建多个ObjectAnimator更节省系统资源
也可以使用Animatorset实现,优点对动画控制提供更好的支持
ObjectAnimator a1 = ObjectAnimator.ofFloat(view1, "rotation",0,360f);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view1, "translationX",0,360);
AnimatorSet set = new AnimatorSet();
set.playTogether(a1, a2);
//set.playSequentially(a1,a2); 控制多个动画依次执行完
//set.play(a1).with(a2); 同时完成a1 a2动画 ,
//set.play(a1).after(a2) 先执行a2动画,再完成a1动画
set.setDuration(1000);
set.start();
查看全部
Interpolators 插值器 有加速Accelerate 减速decelerate 移出再回收overshoot 回弹bounce
使用
animator.setInterpolator(new 插值器);
查看全部
除了ValueAnimator.ofInt(),还有其他类型的数字生成器,其中ValueAnimator.ofObject()可以实现自定义的数字生成器。
参数中的fraction就是时间因子(0到1之间变化的数值)。通过fraction、startValue、endValue,通过各种各样的计算方式,就可以生成所有想要产生的值,不光能产生普通数据结构,通过泛型还可以定义更为复杂的数据结构。
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator() {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
return null;
}
});
生成泛型PointF(float类型的点坐标):
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
return null;
}
});
在方法evaluate()中可以添加各种各样的计算方式。
----------
第二重境界学无止境,ValueAnimator不仅仅可以应用于动画,也可以应用于Android的其他领域。
查看全部
如图是实现菜单弹出和回收的代码
其余代码:
全局变量:
private int[] res={R.id.imageView_a,R.id.imageView_b,R.id.imageView_c,R.id.imageView_d,
R.id.imageView_e,R.id.imageView_f,R.id.imageView_g,R.id.imageView_h,};
private List imageViewList = new ArrayList();
private boolean flag = true;
在 onCreate() 中进行ImageView初始化和点击事件的绑定:
for (int i=0;i
ImageView imageView = (ImageView)findViewById(res[i]);
imageView.setOnClickListener(this);
imageViewList.add(imageView);
}
在点击事件doClick()中对第一个图进行判断:
switch (v.getId()){
case R.id.imageView_a:
if(flag){
stratAnim();
}else {
closeAnim();
}
break;
default:
Toast.makeText(this, "点击了"+v.getId(), Toast.LENGTH_SHORT).show();
break
}
这里列举了几种插值器(以下都只是前缀,例如Accelerate表示AccelerateInterpolator):
Accelerate 加速变化
Decelerate 减速变化
AccelerateDecelerate 先加速再减速
Overshoot 在结束之前会超出预定位置一点点,然后回到预定位置
Bounce 最常见的回弹动画,例如自由落体的小球的回弹效果就是通过这样一个插值器实现的。
查看全部
以下摘自评论区:
(float) (Math.sin(Math.toRadians((i - 1) * 90 / (6 - 1))) * 200)
其中,6是要展开的图标数,200是半径。
按照上面程序加入translationX,和translationY中可以以扇形展开。
------------
案例中这个程序有一个bug,就是当动画还未完全展开的时候,此时再点击红色按钮,程序会响应回收图片的事件,由于图片还未完全展开,导致出现动画展开和回收一起出现的混乱场面。
-------------
解决动画期间按钮可以点击的bug:在for循环外面增加ObjectAnimator的addListener的onAnimationEnd方法,在startAnim开始时设置按钮不可点击:mImageViews.get(0).setEnabled(false),在onAnimationEnd方法中恢复按钮点击事件:mImageViews.get(0).setEnabled(true),endAnim()同理。
---------------
设置两个flag,第一个是记录菜单打开关闭的flag1,第二个是记录菜单是否处于动画中的flag2;
第二个记录处于动画中的flag2在进入for循环前改变状态成true;
第一个flag1 状态改变放在最后一个objectanimator的监听事件onAnimationEnd里,第二个flag2状态也在这里重新切换成false(因为到这里动画已经结束了)
放出菜单的判断是if(flag1&&!flag2)
放出收回菜单的判断是else if(!flag&&!flag2)
这样在动画中就不会再次触发动画了。
查看全部
Animator同样支持AnimatorSet,增加动画组合的多样性
playSequentially:按顺序进行动画的播放
playTogether:一起执行所选的动画效果
还可以进行属性集合的详细控制
set.play(动画2).with(动画3);
set.play(动画1).after(动画2);
ObjectAnimatior.ofFloat()方法实现的动画是同时进行的,同时操作多个属性的动画可以使用ofPropertyValuesHolder方法
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0,360F);
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX",0,360F);
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationY",0,360F);
ObjectAnimatior.ofPropertyValuesHolder(imageView,p1,p2,p3).setDuration(1000).start();
好处是便于多种动画的组合和复用
属性动画平移的实现方法
ObjectAnimatior.ofFloat(imageView,"translationX",0F,200f).setDuration(1000).start();
//ofFloat方法(要操作的对象,"要操作的元素",变化范围,变化范围).设置持续时间.开始执行
要操作的元素只要包含get和set方法都可以使用属性动画,例如
translationX/translationY:X/Y轴的偏移量
X/Y:X/Y的最终量
rotation:旋转,从0度开始
查看全部
使用AnimatorSet来完成 {
AnimatorSet set = new AnimatorSet();
ObjectAnimator animator1 = ObjectAnimator.offloat(imageView, "rotation", 0f, 200f);
ObjectAnimator animator2 = ObjectAnimator.offloat(imageView, "translationX", 0f, 200f);
ObjectAnimator animator3 = ObjectAnimator.offloat(imageView, "translationY", 0f, 200f);
set.playTogether(animator1,animator2,animator3); // 动画一起播放
// set.playSequentially(animator1,animator2,animator3); // 顺序播放动画
// 控制动画之间的播放顺序
// set.play(animator2).with(animator3); // 先X和Y一起平移
// set.play(animator1).after(animator3); // 平移完成之后旋转
set.setDuration(1000);
set.start();
}
查看全部
一、ObjectAnimator属性动画
1.ObjectAnimator.ofFloat(view,"",float,float).setDuration(1000).start();
第二个参数:
translationX、translationY偏移量
rotation旋转
X、Y偏移至
2.同时作用三个属性动画
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0,360f);
ObjectAnimator.ofPropertyValuesHolder(view,p1,p2,p3).setDuration(1000).start();
二、AnimatorSet
1.同时作用三个属性动画
ObjectAnimator animator1 = ObjectAnimator.ofFloat(view,"rotation",0,360F);
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1,animator2,animator3);
set.start();
2.顺次播放动画
set.playSequentially(animator1,animator2,animator3);
3.组合动画
set.play(animator2).with(animator3);
set.play(animator1).after(animator2);
动画二和动画三同时播放,结束后播放动画一
查看全部
属性动画框架可以代替传统的Animation框架
属性动画中最简单也最常用的一个对象——ObjectAnimator
ObjectAnimator可以操作很多的属性,只要我们发现一个对象的属性有get和set方法,那么我们就可以通过ObjectAnimator操作它的属性,从而实现特定的动画。
ObjectAnimator调用start()进行动画是异步的,所以如果我们同时开始三个属性动画,那么这三个动画是同时作用的
查看全部
ImageView imageView=(ImageView) this.findViewById(R.id.imageView1);
ObjectAnimator animator1=ObjectAnimator.ofFloat(imageView, "rotation", 0,360F);
ObjectAnimator animator2=ObjectAnimator.ofFloat(imageView, "translationX", 0F,400F);
ObjectAnimator animator3=ObjectAnimator.ofFloat(imageView, "translationY", 0F,400F);
AnimatorSet set=new AnimatorSet();
//set.playTogether(animator1,animator2,animator3); //三个属性动画同时进行
//set.playSequentially(animator1,animator2,animator3); //三个属性动画按顺序进行播放
set.play(animator2).with(animator3); //先在X轴,Y轴同时平移,到达对角线时,在旋转
set.play(animator1).after(animator2);
set.setDuration(2000); //设置显示时长
set.start(); //启动动画
查看全部
/*3
ImageView imageView=(ImageView) this.findViewById(R.id.imageView1);
PropertyValuesHolder p1=PropertyValuesHolder.ofFloat("rotation", 0,360F);
PropertyValuesHolder p2=PropertyValuesHolder.ofFloat("translationX", 0,400F);
PropertyValuesHolder p3=PropertyValuesHolder.ofFloat("translationY", 0,360F);
ObjectAnimator.ofPropertyValuesHolder(imageView, p1,p2,p3).setDuration(3000).start();
*/
/* PropertyValuesHolder p1=PropertyValuesHolder.ofFloat(propertyName, values);
* propertyName:是属性
* value:是属性变化的值
* ObjectAnimator.ofPropertyValuesHolder(target, values);
* target:所要作用动画的对象
* values:可变长数组
* */
查看全部
fFloat(imageView, "translationX", 400F,-10F).setDuration(5000).start();
ObjectAnimator.ofFloat(imageView, "rotation", 0F,360F).setDuration(4000).start();
*/
/*动画进行是异步的
* target:所要操作的对象,这里是ImageView
* propertyName:所需要操作的属性
* value:动画变化的范围
* setDuration:用于设置动画时长
* translationX,translationY 指的是物体的偏移量
* X,Y 指最终动画所到达的绝对位置
* rotation 设置动画旋转
* */
查看全部
除了ValueAnimator.ofInt(),还有其他类型的数字生成器,其中ValueAnimator.ofObject()可以实现自定义的数字生成器。
参数中的fraction就是时间因子(0到1之间变化的数值)。通过fraction、startValue、endValue,通过各种各样的计算方式,就可以生成所有想要产生的值,不光能产生普通数据结构,通过泛型还可以定义更为复杂的数据结构。
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator() {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
return null;
}
});
生成泛型PointF(float类型的点坐标):
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
return null;
}
});
在方法evaluate()中可以添加各种各样的计算方式。
----------
第二重境界学无止境,ValueAnimator不仅仅可以应用于动画,也可以应用于Android的其他领域。
查看全部
ValueAnimator数值发生器
产生数值
ofInt(1,100)
ValueAnimator的addUpdateListener()监听获取每一步产生的数值
----------------在匿名内部类中通过getAnimatedValue()方法获得数值
自定义数值发生器:
ValueAnimator.ofObject(new TypeEvaluator(){实现evaluate(0-1的时间因子,开始,结束值)方法})
查看全部
Interpolator总结:
- AccelerateInterpolator --加速
- AnticipateInterpolator --先减速后加速
- LinearInterpolator --线性变化
- DecelerateInterpolator --减速
- BounceInterpolator --弹跳小球
- OvershootInterpolator --
查看全部
为属性动画添加监听器:
直接使用ObjectAnimator对象的addListener()方法,传入一个Animator.AnimatorListener接口对象即可添加监听器。
谷歌提供了一个子类:AnimatorListenerAdapter,,使用该类的对象即可任意覆盖父类方法,节约代码量
查看全部
如图是实现菜单弹出和回收的代码
其余代码:
全局变量:
private int[] res={R.id.imageView_a,R.id.imageView_b,R.id.imageView_c,R.id.imageView_d,
R.id.imageView_e,R.id.imageView_f,R.id.imageView_g,R.id.imageView_h,};
private List imageViewList = new ArrayList();
private boolean flag = true;
在 onCreate() 中进行ImageView初始化和点击事件的绑定:
for (int i=0;i
ImageView imageView = (ImageView)findViewById(res[i]);
imageView.setOnClickListener(this);
imageViewList.add(imageView);
}
在点击事件doClick()中对第一个图进行判断:
switch (v.getId()){
case R.id.imageView_a:
if(flag){
stratAnim();
}else {
closeAnim();
}
break;
default:
Toast.makeText(this, "点击了"+v.getId(), Toast.LENGTH_SHORT).show();
break
}
这里列举了几种插值器(以下都只是前缀,例如Accelerate表示AccelerateInterpolator):
Accelerate 加速变化
Decelerate 减速变化
AccelerateDecelerate 先加速再减速
Overshoot 在结束之前会超出预定位置一点点,然后回到预定位置
Bounce 最常见的回弹动画,例如自由落体的小球的回弹效果就是通过这样一个插值器实现的。
查看全部
属性动画
ObjectAnimator.ofFloat(第一个参数,第二个参数,第三个参数)
ps:第一个动画是我们要控制的对象,第二个参数是我们要控制的属性,第三个参数是属性变化的范围。因为是参数类型是float所以我们要在数字后面加F。translationX是相对便宜的位移,而X则是最终要到达的位置。
查看全部
ObjectAnimator.ofFloat(第一个参数,"rotation",第三个参数)截图中意味着控制旋转属性,使要控制的对象也就是图片旋转360度
查看全部