Android动画之属性动画(PropertyAnimation)详解(一)
2017-02-04 14:49
309 查看
转载请注明出处:http://blog.csdn.net/xiaohao0724/article/details/54863112
前面我们学习了补间动画,今天我们来学习可以代替补间动画的属性动画 Property Animation
我们先来看一下补间动画和属性动画的区别:
补间动画通过动画改变控件的位置时,只是改变了View的显示效果并不会真正的改变View的属性(如View的真实位置等),控件的作用域还在原地,而且补间动画是只能够作用在View上。
属性动画通过动画改变控件的位置时,控件的真实位置会随着改变,控件的作用域在变换后的位置。
下面我们就来学习属性动画的平移、缩放、旋转、透明度变化和属性动画的一些组合动画。
属性动画的平移、缩放、旋转、透明度变化
属性动画的组合动画
AnimationProperty.java
PropertyAnimationActivity.java
activity_property.XML
在代码中调用ObjectAnimator.ofFloat(imageView,"translationX", 0, 50, 100, 150, 200, 250, 300);
意思就是ObjectAnimator会不断地改变imageView对象的translationX属性的值从0变化到300。然后imageView对象根据translationX属性值的改变来不断刷新界面的显示,产生横向移动的动画效果。
ObjectAnimator是如何进行操作的呢?ObjectAnimator内部的工作机制是去寻找translationX这个属性名对应的get和set方法:
public void setTranslationX(float value);
public float getTranslationX();
imageView中确实有这两个方法:
imageView.getTranslationX();
imageView.setTranslationX(translationX);
这两个方法是由其父类View对象提供,所以使用ObjectAnimator.ofFloat()调用属性动画时对应的控件必须要有set和get方法。其他的scaleX,rotationX,alpha也是一样的道理。
注:使用ValueAnimator掉用属性动画时不需要其控件必须有set和get方法。
PropertyGroupAnimationActivity.java
activity_property_group.XML
点击下载源码
前面我们学习了补间动画,今天我们来学习可以代替补间动画的属性动画 Property Animation
我们先来看一下补间动画和属性动画的区别:
补间动画通过动画改变控件的位置时,只是改变了View的显示效果并不会真正的改变View的属性(如View的真实位置等),控件的作用域还在原地,而且补间动画是只能够作用在View上。
属性动画通过动画改变控件的位置时,控件的真实位置会随着改变,控件的作用域在变换后的位置。
下面我们就来学习属性动画的平移、缩放、旋转、透明度变化和属性动画的一些组合动画。
属性动画的平移、缩放、旋转、透明度变化
属性动画的组合动画
一、先来看属性动画的平移、缩放、旋转、透明度变化
代码实现如下:AnimationProperty.java
public class AnimationProperty { public static ObjectAnimator setAnimProperty(ObjectAnimator objectAnimator) { // objectAnimator.setRepeatCount(2); // 动画重复次数 // 动画重复模式分别为:RESTART(重新播放)和REVERSE(往返播放)两种 // objectAnimator.setRepeatMode(ObjectAnimator.RESTART); objectAnimator.setDuration(2000); // 动画播放时长 // objectAnimator.start(); //开启动画 // objectAnimator.setStartDelay(2000); // 延时开启动画 // objectAnimator.cancel(); //停止动画 // objectAnimator.end(); //直接到最终状态 return objectAnimator; } public static ValueAnimator setAnimProperty(ValueAnimator valueAnimator) { valueAnimator.setRepeatCount(2); valueAnimator.setRepeatMode(ObjectAnimator.RESTART); valueAnimator.setDuration(2000).start(); return valueAnimator; } }
PropertyAnimationActivity.java
public class PropertyAnimationActivity extends Activity { protected static final String TAG = "Havorld"; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_property); imageView = (ImageView) findViewById(R.id.iv); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getApplicationContext(), "点击了图片", Toast.LENGTH_SHORT).show(); } }); } /** * 平移动画 */ public void trans(View view) { /** * imageView: 要作用的控件; translationY: 要作用动作的属性名 ; float... values: * 可变参数是依次移动的位移 * */ // ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, // "translationY", 20, 40, 80, 120, 160); //竖直平移 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "translationX", 0, 50, 100, 150, 200, 250, 300); // 水平平移 // 监听动画是否成功执行 objectAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float currentValue = (Float) animation.getAnimatedValue(); Log.i(TAG, "currentValue:" + currentValue); // 直接设置动画 // imageView.setTranslationX(translationX); // imageView.setTranslationY(translationY); // imageView.setScaleX(caleX); // imageView.setScaleY(scaleY); // imageView.setRotation(rotation); // imageView.setRotationX(rotation); // imageView.setRotationY(rotation); // imageView.setImageAlpha(alpha); // imageView.setAlpha(alpha); } }); // 动画监听 objectAnimator.addListener(new AnimatorListener() { // 动画开始执行 @Override public void onAnimationStart(Animator animation) { Log.e(TAG, "onAnimationStart"); } // 动画重复执行 @Override public void onAnimationRepeat(Animator animation) { Log.e(TAG, "onAnimationRepeat"); } // 动画执行完成 @Override public void onAnimationEnd(Animator animation) { // 获取控件平移的距离 float translationX = imageView.getTranslationX(); Log.e(TAG, "translationX:" + translationX); } // 动画取消执行 @Override public void onAnimationCancel(Animator animation) { Log.e(TAG, "onAnimationCancel"); } }); // 简化上述动画监听,可以复写上面的任意方法 objectAnimator.addListener(new AnimatorListenerAdapter() { }); // 设置动画属性并开启动画 AnimationProperty.setAnimProperty(objectAnimator).start(); // XmlTranslation(); // valueAnimator(); } /** * 通过XML设置平移 */ private void XmlTranslation() { // 通过XML设置属性动画 Animator animator = AnimatorInflater.loadAnimator(this, R.animator.object_animator_translationx); animator.setTarget(imageView); animator.start(); } /** * 通过ValueAnimator设置平移 */ private void valueAnimator() { ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1000); valueAnimator.setTarget(imageView); AnimationProperty.setAnimProperty(valueAnimator); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float animatedValue = (Float) animation.getAnimatedValue(); imageView.setTranslationY(animatedValue); } }); } /** * 缩放动画 */ public void scale(View view) { // 横向缩放 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "scaleX", 1.0f, 1.2f, 1.5f, 1.8f, 2.0f, 1.8f, 1.5f, 1.0f); // 纵向缩放 // ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, // "scaleY", 1.0f, 1.2f, 1.5f, 1.8f, 2.0f,1.8f, 0.5f,1.0f); // 通过代码设置属性动画 AnimationProperty.setAnimProperty(objectAnimator).start(); } /** * 旋转动画 */ public void rotate(View view) { ObjectAnimator objectAnimator = ObjectAnimator .ofFloat(imageView, "rotationX", 0, 60, 120, 150, 180, 210, 240, 270, 300, 330, 360); AnimationProperty.setAnimProperty(objectAnimator).start(); } /** * 透明度变化动画 */ public void alpha(View view) { ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 0, 0.1f, 0.3f, 0.5f, 0.8f, 1.0f); AnimationProperty.setAnimProperty(objectAnimator).start(); } }
activity_property.XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" tools:context=".PropertyAnimationActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="trans" android:text="平移" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="scale" android:text="缩放" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="rotate" android:text="旋转" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="alpha" android:text="透明" /> </LinearLayout> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp" android:src="@drawable/cl" /> </LinearLayout>
在代码中调用ObjectAnimator.ofFloat(imageView,"translationX", 0, 50, 100, 150, 200, 250, 300);
意思就是ObjectAnimator会不断地改变imageView对象的translationX属性的值从0变化到300。然后imageView对象根据translationX属性值的改变来不断刷新界面的显示,产生横向移动的动画效果。
ObjectAnimator是如何进行操作的呢?ObjectAnimator内部的工作机制是去寻找translationX这个属性名对应的get和set方法:
public void setTranslationX(float value);
public float getTranslationX();
imageView中确实有这两个方法:
imageView.getTranslationX();
imageView.setTranslationX(translationX);
这两个方法是由其父类View对象提供,所以使用ObjectAnimator.ofFloat()调用属性动画时对应的控件必须要有set和get方法。其他的scaleX,rotationX,alpha也是一样的道理。
注:使用ValueAnimator掉用属性动画时不需要其控件必须有set和get方法。
二、接下来看属性动画的组合动画
直接上代码:PropertyGroupAnimationActivity.java
public class PropertyGroupAnimationActivity extends Activity { protected static final String TAG = "Havorld"; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_property_group); imageView = (ImageView) findViewById(R.id.iv); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getApplicationContext(), "点击了图片", Toast.LENGTH_SHORT).show(); } }); } /** * 组合动画一 */ public void animatorSet(View view) { AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator translationXAnimation = AnimationProperty .setAnimProperty(ObjectAnimator.ofFloat(imageView, "translationX", 0, 10, 20, 30, 40, 50)); ObjectAnimator translationYAnimation = AnimationProperty .setAnimProperty(ObjectAnimator.ofFloat(imageView, "translationY", 0, 20, 40, 80, 100)); ObjectAnimator scaleXAnimation = AnimationProperty .setAnimProperty(ObjectAnimator.ofFloat(imageView, "scaleX", 1.0f, 1.2f, 1.5f, 1.8f, 2.0f, 1.8f, 1.5f, 1.0f)); ObjectAnimator rotationAnimation = AnimationProperty .setAnimProperty(ObjectAnimator.ofFloat(imageView, "rotation", 0, 60, 120, 150, 180, 210, 240, 270, 300, 330, 360)); ObjectAnimator alphaAnimation = AnimationProperty .setAnimProperty(ObjectAnimator.ofFloat(imageView, "alpha", 0, 0.1f, 0.3f, 0.5f, 0.8f, 1.0f)); // after(Animator anim) 将现有动画插入到传入的动画之后执行 // after(long delay) 将现有动画延迟指定毫秒后执行 // before(Animator anim) 将现有动画插入到传入的动画之前执行 // with(Animator anim) 将现有动画和传入的动画同时执行 // 按顺序播放动画组合方法一,弦播放alphaAnimation动画后,开始一块播放translationXAnimation和translationYAnimation动画, // 完了之后再一块播放scaleXAnimation和rotationAnimation // animatorSet.play(translationXAnimation).with(translationYAnimation); // animatorSet.play(scaleXAnimation).with(rotationAnimation) // .after(alphaAnimation); // 按顺序播放动画组合方法二 // animatorSet.playSequentially(translationXAnimation,translationYAnimation,scaleXAnimation,rotationAnimation,alphaAnimation); // 组合动画 animatorSet.playTogether(translationXAnimation, translationYAnimation, scaleXAnimation, rotationAnimation, alphaAnimation); animatorSet.start(); } /** * 组合动画二 */ public void viewProperty(View view) { ViewPropertyAnimator viewPropertyAnimator = imageView.animate(); viewPropertyAnimator.x(20).y(30);//移动到坐标(20,30)处 viewPropertyAnimator.alpha(0.5f);//设置控件透明度为0.5 } /** * 组合动画三 */ public void propertyValuesHolder(View view) { PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f); PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f); PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f); PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat( "rotation", 0, 90); ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder( imageView, alpha, scaleX, scaleY, rotation); AnimationProperty.setAnimProperty(objectAnimator).start(); } /** * 一个动画实现多个效果 */ public void groupAnimation(View view) { ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "Havorld", 1.0F, 1.5F); ObjectAnimator objectAnimator = AnimationProperty .setAnimProperty(animator); //监听动画的执行 objectAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float animatedValue = (Float) animation.getAnimatedValue(); Log.e(TAG, "animatedValue:" + animatedValue); imageView.setAlpha(animatedValue); imageView.setScaleX(animatedValue); imageView.setScaleY(animatedValue); } }); objectAnimator.start(); } }
activity_property_group.XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".PropertyAnimationActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="animatorSet" android:text="AnimatorSet" android:textSize="12sp" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="viewProperty" android:text="ViewProperty" android:textSize="12sp" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ellipsize="end" android:onClick="propertyValuesHolder" android:singleLine="true" android:text="propertyValuesHolder" android:textSize="12sp" /> </LinearLayout> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp" android:src="@drawable/cl" /> </LinearLayout>
点击下载源码
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件