动画实现的功能描述:类似于画廊的功能,点击其中一个图片的缩略图,然后全屏打开这个图片,中间的过程用动画实现,给操作者一个从缩略图放大到全屏的感觉。
由上述的描述可以看出,用户点击缩略图的位置是不固定的,所以动画的起始位置是不固定的,而且有的特殊情况下可能动画起始是视图的大小也是不固定的,所以用anim的xml定义实现是不可能的,所以这里我用将用手写AnimationSet的方式实现这个动画。
示例程序描述:
本示例是通过点击不同位置上的button,然后通过动画弹出一个LinearLayout,点击这个LinearLayout,然后又通过动画的方式隐藏这个LinearLayout。
第一步,创建一个工程,在初始的main.xml中添加多个button
本例是添加了6个button,具体代码就不再贴出了。样子就是这样的:
第二步,给每个button添加上点击事件
可以通过xml上的android:onClick="btnOnClick"属性声明点击事件,然后在相应的Activity上实现这个方法就可以了,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public void btnOnClick(View btn) { 2 showView(btn); 3 }
第三步,实现弹出动画和隐藏动画
显示动画如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 AnimationSet animSet = new AnimationSet(true); 2 ScaleAnimation sa = new ScaleAnimation((float) v.getWidth() 3 / ((View) v.getParent()).getWidth(), 1.0f, 4 (float) v.getHeight() / ((View) v.getParent()).getHeight(), 5 1.0f, v.getX() + v.getWidth() / 2, v.getY() + v.getHeight() / 2); 6 sa.setDuration(2000); 7 AlphaAnimation aa = new AlphaAnimation(0.2f, 1); 8 aa.setDuration(2000); 9 animSet.addAnimation(sa); 10 animSet.addAnimation(aa);
隐藏动画如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 AnimationSet animSet = new AnimationSet(true); 2 ScaleAnimation sa = new ScaleAnimation(1, (float) v.getWidth() 3 / ((View) v.getParent()).getWidth(), 1, (float) v.getHeight() 4 / ((View) v.getParent()).getHeight(), v.getX() + v.getWidth() 5 / 2, v.getY() + v.getHeight() / 2); 6 sa.setDuration(2000); 7 AlphaAnimation aa = new AlphaAnimation(1f, 0f); 8 aa.setDuration(2000); 9 animSet.addAnimation(sa); 10 animSet.addAnimation(aa);
综上所述,整个示例的核心代码就是Activity的2个方法,Activity的源代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class AnimTestActivity extends Activity { 2 private LinearLayout mView = null; 3 4 /** Called when the activity is first created. */ 5 @Override 6 public void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.main); 9 } 10 11 public void btnOnClick(View btn) { 12 showView(btn); 13 } 14 15 private void showView(final View v) { 16 if (mView == null) { 17 mView = new LinearLayout(this); 18 mView.setBackgroundColor(Color.BLUE); 19 addContentView(mView, new ViewGroup.LayoutParams( 20 LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 21 } 22 mView.setOnClickListener(new View.OnClickListener() { 23 @Override 24 public void onClick(View view) { 25 hideView(v); 26 } 27 }); 28 29 AnimationSet animSet = new AnimationSet(true); 30 ScaleAnimation sa = new ScaleAnimation((float) v.getWidth() 31 / ((View) v.getParent()).getWidth(), 1.0f, 32 (float) v.getHeight() / ((View) v.getParent()).getHeight(), 33 1.0f, v.getX() + v.getWidth() / 2, v.getY() + v.getHeight() / 2); 34 sa.setDuration(2000); 35 AlphaAnimation aa = new AlphaAnimation(0.2f, 1); 36 aa.setDuration(2000); 37 animSet.addAnimation(sa); 38 animSet.addAnimation(aa); 39 mView.startAnimation(animSet); 40 mView.setVisibility(View.VISIBLE); 41 } 42 43 private void hideView(View v) { 44 AnimationSet animSet = new AnimationSet(true); 45 ScaleAnimation sa = new ScaleAnimation(1, (float) v.getWidth() 46 / ((View) v.getParent()).getWidth(), 1, (float) v.getHeight() 47 / ((View) v.getParent()).getHeight(), v.getX() + v.getWidth() 48 / 2, v.getY() + v.getHeight() / 2); 49 sa.setDuration(2000); 50 AlphaAnimation aa = new AlphaAnimation(1f, 0f); 51 aa.setDuration(2000); 52 animSet.addAnimation(sa); 53 animSet.addAnimation(aa); 54 mView.startAnimation(animSet); 55 mView.setVisibility(View.GONE); 56 } 57 }
有一点需要说明一下:(float) v.getWidth() / ((View) v.getParent()).getWidth()
- v.getWidth() 和 ((View) v.getParent()).getWidth()都是int类型,为了不让得到的结果为0,这里用float转换了一下分子
- v.getWidth() 在弹出动画中代表的是动画起始时视图的大小,在隐藏动画中代表的是动画结束时视图的大小
- ((View) v.getParent()).getWidth()在弹出动画中代表的是动画结束时的视图的大小,在隐藏动画中代表的是动画开始时视图的大小
- 这个比值的结果是动画变化前后的宽度的比值