近期学习Android属性动画和VetcorDrawable实现属性动画,以此记录一下学习笔记。
首先是属性动画,小白没截过动态图,方三张静态图吧
效果是点击红色图片,7个选项以属性动画的方式弹出并旋转,最后成一个1/4圆弧排列,再次点击则收回到红色原点下。
布局文件很简单,就是一个RelativeLayout下八个ImageView:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <RelativeLayout 8 android:gravity="center" 9 android:layout_width="match_parent"10 android:layout_height="match_parent">11 12 <ImageView13 android:layout_marginTop="5dp"14 android:layout_marginLeft="5dp"15 android:layout_width="24dp"16 android:layout_height="24dp"17 android:id="@+id/iv_b"18 android:src="@drawable/b"19 />20 <ImageView21 android:layout_marginTop="5dp"22 android:layout_marginLeft="5dp"23 android:layout_width="24dp"24 android:layout_height="24dp"25 android:id="@+id/iv_c"26 android:src="@drawable/c"27 />28 <ImageView29 android:layout_marginTop="5dp"30 android:layout_marginLeft="5dp"31 android:layout_width="24dp"32 android:layout_height="24dp"33 android:id="@+id/iv_d"34 android:src="@drawable/d"35 />36 <ImageView37 android:layout_marginTop="5dp"38 android:layout_marginLeft="5dp"39 android:layout_width="24dp"40 android:layout_height="24dp"41 android:id="@+id/iv_e"42 android:src="@drawable/e"43 />44 <ImageView45 android:layout_marginTop="5dp"46 android:layout_marginLeft="5dp"47 android:layout_width="24dp"48 android:layout_height="24dp"49 android:id="@+id/iv_f"50 android:src="@drawable/f"51 />52 <ImageView53 android:layout_marginTop="5dp"54 android:layout_marginLeft="5dp"55 android:layout_width="24dp"56 android:layout_height="24dp"57 android:id="@+id/iv_g"58 android:src="@drawable/g"59 />60 <ImageView61 android:layout_marginTop="5dp"62 android:layout_marginLeft="5dp"63 android:layout_width="24dp"64 android:layout_height="24dp"65 android:id="@+id/iv_h"66 android:src="@drawable/h"67 />68 <ImageView69 android:layout_width="40dp"70 android:layout_height="40dp"71 android:id="@+id/iv_a"72 android:src="@drawable/a"73 />74 75 </RelativeLayout>76 77 </LinearLayout>
接下来在MainActivity中,定义一个装有动画效果的ImageView的集合;所有ImageView的id的int数组;还有一个角度用来计算呈半圆排列时,每个图片的坐标;还有个boolean型flag用来判断点击是弹出还是回收:
1 private List<ImageView> imageViewList = new ArrayList<ImageView>();2 private int[] res = new int[]{R.id.iv_a, R.id.iv_b, R.id.iv_c, R.id.iv_d, R.id.iv_e, R.id.iv_f, R.id.iv_g, R.id.iv_h};3 private boolean flag = true;4 private static double ANGLE = Math.PI/12;
接着是onCreate以及初始化控件和点击事件方法
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 setContentView(R.layout.activity_main); 5 6 initView(); 7 } 8 9 private void initView() {10 for(int i = 0; i < res.length; i++) {11 ImageView imageView = (ImageView) findViewById(res[i]);12 imageView.setOnClickListener(this);13 imageViewList.add(imageView);14 }15 }16 17 @Override18 public void onClick(View view) {19 switch (view.getId()) {20 case R.id.iv_a:21 if(flag) {22 startAnim();23 } else {24 stopAnim();25 }26 27 break;28 }29 }
最后则是重点,动画代码,也就是上面onClick方法里调用的startAnim()和stopAnim()所封装的弹出和收回两个方法:
1 //收回动画 2 private void stopAnim() { 3 for(int i = res.length - 1; i > 0; i--) { 4 ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", Math.round(300*(Math.cos((i-1)*ANGLE))), 0F); 5 animatorX.setDuration(500); 6 ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", Math.round(300*(Math.sin((i-1)*ANGLE))), 0F); 7 animatorY.setDuration(500); 8 ObjectAnimator animatorRotation = ObjectAnimator.ofFloat(imageViewList.get(i), "rotation", 5*360F, 0F); 9 animator.setDuration(500);10 AnimatorSet set = new AnimatorSet();11 set.play(animatorX).with(animatorY).with(animatorRotation);12 set.setStartDelay(i*300);13 set.start();14 flag = true;15 }16 }17 18 //弹出动画19 private void startAnim() {20 for(int i = 1; i < res.length; i++) {21 ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", 0F, Math.round(300*(Math.cos((i-1)*ANGLE))));22 animatorX.setDuration(500);23 ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0F, Math.round(300*(Math.sin((i-1)*ANGLE))));24 animatorY.setDuration(500);25 ObjectAnimator animatorRotation = ObjectAnimator.ofFloat(imageViewList.get(i), "rotation", 0F, 5*360F);26 animator.setDuration(500);27 AnimatorSet set = new AnimatorSet();28 set.play(animatorX).with(animatorY).with(animatorRotation);29 set.setStartDelay(i*300);30 set.start();31 flag = false;32 }33 }
三个属性动画分别是X轴,Y轴移动,和旋转;
ObjectAnimator的ofFloat的四个参数分别是需要执行动画的对象,动画的种类的属性名,开始时候的位置,结束时候的位置;
其中AnimatorSet的with是用于将三个动画同时展现,还有after用于控制顺序的;setStartDelay则是延迟展现,保证7张图片不要一下子全部弹出来,这些也可以根据具体需要进行修改组合。
最后感谢慕课网的eclipse_xu老师,这篇笔记正是看了徐老师的课程才写下的,收益颇丰,再次感谢!