http://blog.csdn.net/lmj623565791/article/details/38092093

http://blog.csdn.net/lmj623565791/article/details/38092093

http://blog.csdn.net/lmj623565791/article/details/38092093




Android 属性动画(Property Animation) 完全解析 (下)

分类:【android 进阶之路】【Android 基础】【Android 源码解析】 2718人阅读 评论(3) 收藏 举报 Android Property Animation

目录(?)[+]

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38092093

上一篇Android 属性动画(Property Animation) 完全解析 (上)已经基本展示了属性动画的核心用法:

ObjectAnimator实现动画,ValueAnimator实现动画,AnimatorSet的使用等~

当然了属性动画还有一部分的知识点,也能做出很不错的效果,将在本篇博客为您展示~

1、如何使用xml文件来创建属性动画

大家肯定都清楚,View Animator 、Drawable Animator都可以在anim文件夹下创建动画,然后在程序中使用,甚至在Theme中设置为属性值。当然了,属性动画其实也可以在文件中声明:

首先在res下建立animator文件夹,然后建立res/animator/scalex.xml

[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <objectAnimatorxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:duration="1000"
  4. android:propertyName="scaleX"
  5. android:valueFrom="1.0"
  6. android:valueTo="2.0"
  7. android:valueType="floatType">
  8. </objectAnimator>
代码:

[java] view plain copy
  1. publicvoidscaleX(Viewview)
  2. {
  3. //加载动画
  4. Animatoranim=AnimatorInflater.loadAnimator(this,R.animator.scalex);
  5. anim.setTarget(mMv);
  6. anim.start();
  7. }
使用AnimatorInflater加载动画的资源文件,然后设置目标,就ok~~是不是很简单,这只是单纯横向的放大一倍~

如果我希望纵向与横向同时缩放呢?则可以怎么定义属性文件:

[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <setxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:ordering="together">
  4. <objectAnimator
  5. android:duration="1000"
  6. android:propertyName="scaleX"
  7. android:valueFrom="1"
  8. android:valueTo="0.5">
  9. </objectAnimator>
  10. <objectAnimator
  11. android:duration="1000"
  12. android:propertyName="scaleY"
  13. android:valueFrom="1"
  14. android:valueTo="0.5">
  15. </objectAnimator>
  16. </set>

使用set标签,有一个orderring属性设置为together,【还有另一个值:sequentially(表示一个接一个执行)】。

上篇博客中忽略了一个效果,就是缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线,所以我决定这个横向,纵向缩小以左上角为中心点:

代码:

[java] view plain copy
  1. //加载动画
  2. Animatoranim=AnimatorInflater.loadAnimator(this,R.animator.scale);
  3. mMv.setPivotX(0);
  4. mMv.setPivotY(0);
  5. //显示的调用invalidate
  6. mMv.invalidate();
  7. anim.setTarget(mMv);
  8. anim.start();

很简单,直接给View设置pivotX和pivotY,然后调用一下invalidate,就ok了。

下面看效果图:

好了,通过写xml声明动画,使用set嵌套set,结合orderring属性,也基本可以实现任何动画~~上面也演示了pivot的设置。

2、布局动画(Layout Animations)

主要使用LayoutTransition为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果。

基本代码为:

[java] view plain copy
  1. LayoutTransitiontransition=newLayoutTransition();
  2. transition.setAnimator(LayoutTransition.CHANGE_APPEARING,
  3. transition.getAnimator(LayoutTransition.CHANGE_APPEARING));
  4. transition.setAnimator(LayoutTransition.APPEARING,
  5. null);
  6. transition.setAnimator(LayoutTransition.DISAPPEARING,
  7. null);
  8. transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,
  9. null);
  10. mGridLayout.setLayoutTransition(transition);

过渡的类型一共有四种:

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设置的动画。

注意动画到底设置在谁身上,此View还是其他View。

好了下面看一个综合的例子:

布局文件:

[html] view plain copy
  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:id="@+id/id_container"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical">
  7. <Button
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:onClick="addBtn"
  11. android:text="addBtns"/>
  12. <CheckBox
  13. android:id="@+id/id_appear"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. android:checked="true"
  17. android:text="APPEARING"/>
  18. <CheckBox
  19. android:id="@+id/id_change_appear"
  20. android:layout_width="wrap_content"
  21. android:layout_height="wrap_content"
  22. android:checked="true"
  23. android:text="CHANGE_APPEARING"/>
  24. <CheckBox
  25. android:id="@+id/id_disappear"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:checked="true"
  29. android:text="DISAPPEARING"/>
  30. <CheckBox
  31. android:id="@+id/id_change_disappear"
  32. android:layout_width="wrap_content"
  33. android:layout_height="wrap_content"
  34. android:checked="true"
  35. android:text="CHANGE_DISAPPEARING"/>
  36. </LinearLayout>

代码:

[java] view plain copy
  1. packagecom.example.zhy_property_animation;
  2. importandroid.animation.LayoutTransition;
  3. importandroid.app.Activity;
  4. importandroid.os.Bundle;
  5. importandroid.view.View;
  6. importandroid.view.View.OnClickListener;
  7. importandroid.view.ViewGroup;
  8. importandroid.widget.Button;
  9. importandroid.widget.CheckBox;
  10. importandroid.widget.CompoundButton;
  11. importandroid.widget.CompoundButton.OnCheckedChangeListener;
  12. importandroid.widget.GridLayout;
  13. publicclassLayoutAnimaActivityextendsActivityimplements
  14. OnCheckedChangeListener
  15. {
  16. privateViewGroupviewGroup;
  17. privateGridLayoutmGridLayout;
  18. privateintmVal;
  19. privateLayoutTransitionmTransition;
  20. privateCheckBoxmAppear,mChangeAppear,mDisAppear,mChangeDisAppear;
  21. @Override
  22. publicvoidonCreate(BundlesavedInstanceState)
  23. {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.layout_animator);
  26. viewGroup=(ViewGroup)findViewById(R.id.id_container);
  27. mAppear=(CheckBox)findViewById(R.id.id_appear);
  28. mChangeAppear=(CheckBox)findViewById(R.id.id_change_appear);
  29. mDisAppear=(CheckBox)findViewById(R.id.id_disappear);
  30. mChangeDisAppear=(CheckBox)findViewById(R.id.id_change_disappear);
  31. mAppear.setOnCheckedChangeListener(this);
  32. mChangeAppear.setOnCheckedChangeListener(this);
  33. mDisAppear.setOnCheckedChangeListener(this);
  34. mChangeDisAppear.setOnCheckedChangeListener(this);
  35. //创建一个GridLayout
  36. mGridLayout=newGridLayout(this);
  37. //设置每列5个按钮
  38. mGridLayout.setColumnCount(5);
  39. //添加到布局中
  40. viewGroup.addView(mGridLayout);
  41. //默认动画全部开启
  42. mTransition=newLayoutTransition();
  43. mGridLayout.setLayoutTransition(mTransition);
  44. }
  45. /**
  46. *添加按钮
  47. *
  48. *@paramview
  49. */
  50. publicvoidaddBtn(Viewview)
  51. {
  52. finalButtonbutton=newButton(this);
  53. button.setText((++mVal)+"");
  54. mGridLayout.addView(button,Math.min(1,mGridLayout.getChildCount()));
  55. button.setOnClickListener(newOnClickListener()
  56. {
  57. @Override
  58. publicvoidonClick(Viewv)
  59. {
  60. mGridLayout.removeView(button);
  61. }
  62. });
  63. }
  64. @Override
  65. publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked)
  66. {
  67. mTransition=newLayoutTransition();
  68. mTransition.setAnimator(
  69. LayoutTransition.APPEARING,
  70. (mAppear.isChecked()?mTransition
  71. .getAnimator(LayoutTransition.APPEARING):null));
  72. mTransition
  73. .setAnimator(
  74. LayoutTransition.CHANGE_APPEARING,
  75. (mChangeAppear.isChecked()?mTransition
  76. .getAnimator(LayoutTransition.CHANGE_APPEARING)
  77. :null));
  78. mTransition.setAnimator(
  79. LayoutTransition.DISAPPEARING,
  80. (mDisAppear.isChecked()?mTransition
  81. .getAnimator(LayoutTransition.DISAPPEARING):null));
  82. mTransition.setAnimator(
  83. LayoutTransition.CHANGE_DISAPPEARING,
  84. (mChangeDisAppear.isChecked()?mTransition
  85. .getAnimator(LayoutTransition.CHANGE_DISAPPEARING)
  86. :null));
  87. mGridLayout.setLayoutTransition(mTransition);
  88. }
  89. }

效果图:


动画有点长,耐心点看,一定要注意,是对当前View还是其他Views设置的动画。

当然了动画支持自定义,还支持设置时间,比如我们修改下,添加的动画为:

[java] view plain copy
  1. mTransition.setAnimator(LayoutTransition.APPEARING,(mAppear
  2. .isChecked()?ObjectAnimator.ofFloat(this,"scaleX",0,1)
  3. :null));

则效果为:


原本的淡入,变成了宽度从中间放大的效果~~是不是还不错~~

3、View的anim方法

在SDK11的时候,给View添加了animate方法,更加方便的实现动画效果。

布局文件:

[html] view plain copy
  1. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. >
  6. <ImageView
  7. android:id="@+id/id_ball"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:src="@drawable/bol_blue"/>
  11. <LinearLayout
  12. android:layout_width="fill_parent"
  13. android:layout_height="wrap_content"
  14. android:layout_alignParentBottom="true"
  15. android:orientation="horizontal">
  16. <Button
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:onClick="viewAnim"
  20. android:text="ViewAnim"/>
  21. <Button
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:onClick="propertyValuesHolder"
  25. android:text="PropertyValuesHolder"/>
  26. </LinearLayout>
  27. </RelativeLayout>
代码:

[java] view plain copy
  1. packagecom.example.zhy_property_animation;
  2. importandroid.animation.ObjectAnimator;
  3. importandroid.animation.PropertyValuesHolder;
  4. importandroid.app.Activity;
  5. importandroid.os.Bundle;
  6. importandroid.util.DisplayMetrics;
  7. importandroid.util.Log;
  8. importandroid.view.View;
  9. importandroid.widget.ImageView;
  10. publicclassViewAnimateActivityextendsActivity
  11. {
  12. protectedstaticfinalStringTAG="ViewAnimateActivity";
  13. privateImageViewmBlueBall;
  14. privatefloatmScreenHeight;
  15. @Override
  16. protectedvoidonCreate(BundlesavedInstanceState)
  17. {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.view_animator);
  20. DisplayMetricsoutMetrics=newDisplayMetrics();
  21. getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
  22. mScreenHeight=outMetrics.heightPixels;
  23. mBlueBall=(ImageView)findViewById(R.id.id_ball);
  24. }
  25. publicvoidviewAnim(Viewview)
  26. {
  27. //needAPI12
  28. mBlueBall.animate()//
  29. .alpha(0)//
  30. .y(mScreenHeight/2).setDuration(1000)
  31. //needAPI12
  32. .withStartAction(newRunnable()
  33. {
  34. @Override
  35. publicvoidrun()
  36. {
  37. Log.e(TAG,"START");
  38. }
  39. //needAPI16
  40. }).withEndAction(newRunnable()
  41. {
  42. @Override
  43. publicvoidrun()
  44. {
  45. Log.e(TAG,"END");
  46. runOnUiThread(newRunnable()
  47. {
  48. @Override
  49. publicvoidrun()
  50. {
  51. mBlueBall.setY(0);
  52. mBlueBall.setAlpha(1.0f);
  53. }
  54. });
  55. }
  56. }).start();
  57. }}

简单的使用mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000).start()就能实现动画~~不过需要SDK11,此后在SDK12,SDK16又分别添加了withStartAction和withEndAction用于在动画前,和动画后执行一些操作。当然也可以.setListener(listener)等操作。

使用ObjectAnimator实现上面的变化,我们可以使用:PropertyValueHolder

[java] view plain copy
  1. PropertyValuesHolderpvhX=PropertyValuesHolder.ofFloat("alpha",1f,
  2. 0f,1f);
  3. PropertyValuesHolderpvhY=PropertyValuesHolder.ofFloat("y",0,
  4. mScreenHeight/2,0);
  5. ObjectAnimator.ofPropertyValuesHolder(mBlueBall,pvhX,pvhY).setDuration(1000).start();

效果与上面一样。

运行结果:




好了,关于属性动画基本所有的用法到此结束~~~~


源码点击下载



更多相关文章

  1. Android布局属性详解
  2. ListView 常用属性
  3. 最近总结的android疑惑
  4. cc
  5. android ImageView scaleType属性
  6. My Android(安卓)Camera Notes
  7. android分割线
  8. 设置控件不可点击
  9. android gps开发

随机推荐

  1. android 情人鸟(情人专属利器)
  2. Android(安卓)内存优化解决方案 (OOM)
  3. Android压缩图片到100K以下并保持不失真
  4. 调试方法之打堆栈加重写控件
  5. Google Nexus 7/Android(安卓)4.1新手入
  6. [转]android 修改ramdisk.img和init.rc &
  7. Flurry 报告:iOS 和 Android(安卓)持续蚕
  8. Android(安卓)ApiDemo分析(九)--Graphics
  9. Android(安卓)知识要点整理(7)----拍照和录
  10. 新博android毕业前