android动画 -- Property Animator
2015-10-19 23:27
615 查看
Property Animation就是通过设置动画的实际动作属性,完成动画效果;
和属性动画相关的类:
ObjectAnimator实现动画:
提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。
动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~
例子:
//设置图片旋转 以X轴为对称轴开始0度 最后360独
//第二个字符串表示: 调用setPropName去设置图片的属性 动画的过程实质就是不断的调用setter方法去设置变化的值
ValueAnimator实现动画
动画监听事件:
即在动画在开始、中途和结束等状态时的事件操作;
XML方式使用动画:
在res/anim下创建xml文件
布局动画(Layout Animator):
布局动画主要使用LayoutTransition类为布局容器设置动画,即容器中某一图像变化而引起整个容器里面的图像而变化的效果 – 过渡效果
LayoutTransition transition = new LayoutTransition();
transition.setAnimator(LayoutTransition.APPEARING,null);
例子:
动态添加按钮,查看效果
和属性动画相关的类:
[code]ObjectAnimator 动画的执行类 ValueAnimator 动画的执行类 AnimatorSet 用于控制一组动画的执行:线性,一起,每个动画的先后执行等。 AnimatorInflater 用户加载属性动画的xml文件 TypeEvaluator 类型估值,主要用于设置动画操作属性的值。(我觉得就是模拟动画过程,实时从模拟过程中获取动画的状态值,位置/尺寸等,将这些属性设置到真正的动画里面去) Time interpolation:时间差值,乍一看不知道是什么,但是我说LinearInterpolator、AccelerateDecelerateInterpolator;动画加载器定义动画的变化率
ObjectAnimator实现动画:
提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。
动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~
例子:
//设置图片旋转 以X轴为对称轴开始0度 最后360独
//第二个字符串表示: 调用setPropName去设置图片的属性 动画的过程实质就是不断的调用setter方法去设置变化的值
[code] public void onRotate(View v){ ObjectAnimator.ofFloat(v, "rotationY", 0.0f, 180.0f).setDuration(1000).start(); }
[code]多个动画效果添加一起执行有以下三种方法:
[code]//多个动作弄在一块 : 可以选择AnimatorSet或者如下添加刷新器 public void onRotate(final View v){ /*方法一: //设置多组ObjectAnimator对象动画效果;设置他们的动画先后关系*/ ObjectAnimator anim1 = ObjectAnimator.ofFloat(v, "scal", 1f, 0.0f).setDuration(1000); ObjectAnimator anim2 = ObjectAnimator.ofFloat(v, "scaleY", 1f, 0.0f).setDuration(1000); ObjectAnimator anim3 = ObjectAnimator.ofFloat(v, "alpha", 1f, 0.0f).setDuration(1000); AnimatorSet aS = new AnimatorSet(); aS.play(anim1).with(anim2); aS.play(anim2).with(anim3); aS.start(); 方法二 setProperty的name随意取,我们最后通过后面的方法获取值就可以 每一帧图像刷新的时候就调用下面的监控函数,在里面我们去设置那个值就可以了 ObjectAnimator anim = ObjectAnimator.ofFloat(v, "scal", 1f, 0.0f).setDuration(1000); anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator arg0) { // TODO Auto-generated method stub float value = (Float) arg0.getAnimatedValue(); v.setAlpha(value); v.setScaleX(value); v.setScaleY(value); Log.i(TAG, "onAnimationUpdate"); } }); anim.start(); 方法三: 通过PropertyValuesHolder设置动画属性,将属性添加到ObjectAnimator里面去即可 PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("scaleX", 0.0f, 1.0f); PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleY", 0.0f, 1.0f); PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("alpha", 0.0f, 1.0f); ObjectAnimator.ofPropertyValuesHolder(v, holder1, holder2, holder3).setDuration(5000).start(); }
ValueAnimator实现动画
[code]单个动画动作使用方法: 在ValueAnimator定义好图形的动画过程,在显示图像刷图像帧的时候实时设置图像的位置,即实现了动画,下面以竖直运动为例:
[code]public void onVertical(View v){ ValueAnimator animator = ValueAnimator.ofFloat(0,mHeight - image.getHeight()); //规定好起始和最终值,这是一个过程 Log.i(TAG, "mHeight: " + mHeight + " image.getHeight(): " + image.getHeight()); animator.setTarget(image); animator.setDuration(2000); animator.start(); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator arg0) { // TODO Auto-generated method stub image.setTranslationY((Float)arg0.getAnimatedValue()); //图像刷帧的时候实时获取值在设置即可 } }); }
[code]多个动作,由于比较复杂,可以使用一个模拟器模拟器过程:
[code] public void onPaowu(View v){ ValueAnimator animator = new ValueAnimator(); animator.setObjectValues(new PointF(0,0)); animator.setInterpolator(new LinearInterpolator()); animator.setDuration(4000); animator.setEvaluator(new TypeEvaluator<PointF>() { //这其实是一个模拟运动过程 我们只是需要模拟过程中图像的属性值 在把值应用刷新到动画里面去即可 @Override public PointF evaluate(float arg0, PointF startValue, PointF endValue) { // TODO Auto-generated method stub //参数1:当前位置参数 //模拟抛物线运动 水平方向 vt 竖直方向:1/2 gt^2 PointF p = new PointF(); p.set(arg0 * 200 * 5, 0.5f * 200 * arg0 * arg0 * 7); return p; } }); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator arg0) { // TODO Auto-generated method stub PointF p = (PointF)arg0.getAnimatedValue(); image.setX(p.x); image.setY(p.y); } }); animator.start(); }
[code]如上,可以看出,设置一个模拟器,自己实时计算里面的值,将返回的值用于View的设置既可
动画监听事件:
即在动画在开始、中途和结束等状态时的事件操作;
[code] animator.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationCancel(Animator arg0) { // TODO Auto-generated method stub } });
[code]AnimatorListener是一个接口,所以每个方法都需要重写,如果只想写其中某一个或几个方法,可以使用AnimatorListenerAdapter,它是AnimatorListener的子类,但是是一个抽象类,每个方法都是空的
XML方式使用动画:
在res/anim下创建xml文件
[code]<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together" > <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1" android:valueTo="0.5" > </objectAnimator> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1" android:valueTo="0.5" > </objectAnimator> </set> Java代码中读取: Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale); //利用AnimatorInflater读取xml文件 mMv.setPivotX(0); mMv.setPivotY(0); //显示的调用invalidate mMv.invalidate(); anim.setTarget(mMv); //设置对象 anim.start();
布局动画(Layout Animator):
布局动画主要使用LayoutTransition类为布局容器设置动画,即容器中某一图像变化而引起整个容器里面的图像而变化的效果 – 过渡效果
LayoutTransition transition = new LayoutTransition();
transition.setAnimator(LayoutTransition.APPEARING,null);
[code]如上设置的过程代码,过渡的效果有四种: LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画 LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画 LayoutTransition.DISAPPEARING 当一个View在ViewGroup中消失时,对此View设置的动画 LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画 LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。
例子:
动态添加按钮,查看效果
[code] private ViewGroup viewGroup; private GridLayout mGridLayout; private int mVal; private LayoutTransition mTransition; private CheckBox mAppear, mChangeAppear, mDisAppear, mChangeDisAppear; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewGroup = (ViewGroup) this.findViewById(R.id.container); mAppear = (CheckBox) findViewById(R.id.id_appear); mChangeAppear = (CheckBox) findViewById(R.id.id_change_appear); mDisAppear = (CheckBox) findViewById(R.id.id_disappear); mChangeDisAppear = (CheckBox) findViewById(R.id.id_change_disappear); mAppear.setOnCheckedChangeListener(this); mChangeAppear.setOnCheckedChangeListener(this); mDisAppear.setOnCheckedChangeListener(this); mChangeDisAppear.setOnCheckedChangeListener(this); // 创建一个GridLayout mGridLayout = new GridLayout(this); // 设置每列5个按钮 mGridLayout.setColumnCount(5); // 添加到布局中 viewGroup.addView(mGridLayout); //默认动画全部开启 mTransition = new LayoutTransition(); mGridLayout.setLayoutTransition(mTransition); } @Override public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // TODO Auto-generated method stub mTransition = new LayoutTransition(); mTransition.setAnimator(LayoutTransition.APPEARING, mAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.APPEARING) : null); mTransition .setAnimator( LayoutTransition.CHANGE_APPEARING, (mChangeAppear.isChecked() ? mTransition .getAnimator(LayoutTransition.CHANGE_APPEARING) : null)); mTransition.setAnimator( LayoutTransition.DISAPPEARING, (mDisAppear.isChecked() ? mTransition .getAnimator(LayoutTransition.DISAPPEARING) : null)); mTransition.setAnimator( LayoutTransition.CHANGE_DISAPPEARING, (mChangeDisAppear.isChecked() ? mTransition .getAnimator(LayoutTransition.CHANGE_DISAPPEARING) : null)); mGridLayout.setLayoutTransition(mTransition); } public void addBtn(View view) { final Button button = new Button(this); button.setText((++mVal) + ""); mGridLayout.addView(button, Math.min(1, mGridLayout.getChildCount())); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mGridLayout.removeView(button); } }); }
相关文章推荐
- android传递数据bundle封装传递map对象
- ViewPager懒加载和事件分发机制图例
- Android adb命令的使用方法
- Android实现图片滚动控件,含页签功能
- Android_05_多线程断点续传下载
- Android五大布局之网格布局
- Android--getAssets().open(xxx)返回值bug;
- android studio导入.so库的正确方法
- apktool 反编译 Input file was not found or was not readable.问题解决方案
- Android SQLite数据库版本更新
- Android 学习(二)---创建应用程序和活动
- Android系统权限和root权限
- Android使用百度地图SDK
- Android性能专项测试之耗电量统计API
- Ubuntu下安装Android Studio
- 清除Android工程中没用到的资源
- Android 学习(一)
- Android 触摸及手势操作GestureDetector
- android SQLite存储简单范例+详细注释(增删查改)
- Android4.x 如何处理Power按键