最近给自已负责的项目里,个别交互增加了一些动画效果。发现了一个很常见的动画效果问题。

问题描述

蓝色框包含的区域是一个停靠在页面底部的浮动菜单。当用户点了左边购物车按钮时,要用一个动画效果:购物车图标从当前位置 滑动到 页面右上角的一个查看购物车按钮上。

一般的实现思路:

这里假设 购物车View 对象为  cartView;页面右上角的 View对象为 rightBtn;

 

 
  1. ImageView cartView = (ImageView) findViewById(R.id.btn_drug_detail_cart); 
  2.                     Button rightBtn = (Button) findViewById(R.id.right_btn); 
  3.                      
  4.                     int[] start_location = new int[2]; 
  5.                     cartView.getLocationInWindow(start_location); 
  6.                    
  7.                     int[] end_location = new int[2]; 
  8.                     rightBtn.getLocationInWindow(end_location); 
  9.                     int endX = end_location[0]; 
  10.                     int endY = end_location[1] - start_location[1]; 
  11.                     Logger.i("endX:"+endX+",endY"+endY); 
  12.                     Animation mTranslateAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endX, TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endY);// 移动 
  13.                     mTranslateAnimation.setDuration(3000); 
  14.                     AnimationSet mAnimationSet=new AnimationSet(false); 
  15.                     mAnimationSet.setFillAfter(true); 
  16.                     mAnimationSet.addAnimation(mTranslateAnimation); 
  17.                     view.startAnimation(mAnimationSet); 
  18.                      

在购物车的单击事件里执行此动画代码,发现 购物车图标是移动了,当移出蓝色区域边框时,消失了。

下面给出页面某小块区域内的组件想要在整个页面滑动的动画效果 实现方法:

原理:

Android Activity视窗根布局是 FrameLayout.我们可以在根布局上面添加我们的动画效果层。然后要想移某一个组件,先把该组件从原父容器移除,再移到我们的动画层里,然后效果展示。需要注意

1.动画层背景为透明 

2.动画层不要绑定事件,不然会影响下面的视图获取事件(一般来说动画层也不会提供用户交互)

给出实现代码:

第一步: (创建我们需要的一些方法)

 

 
  1. /** 
  2.      * @Description: 创建动画层 
  3.      * @param  
  4.      * @return void 
  5.      * @throws 
  6.      */ 
  7.     private ViewGroup createAnimLayout(){ 
  8.         ViewGroup rootView = (ViewGroup)this.getWindow().getDecorView(); 
  9.         LinearLayout animLayout = new LinearLayout(this); 
  10.         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); 
  11.         animLayout.setLayoutParams(lp); 
  12.         animLayout.setId(R.id.anim_mask_layout); 
  13.         animLayout.setBackgroundResource(android.R.color.transparent); 
  14.         rootView.addView(animLayout); 
  15.         return animLayout; 
  16.     } 
  17.      
  18.     /** 
  19.      * @Description: 添加视图到动画层 
  20.      * @param @param vg 
  21.      * @param @param view 
  22.      * @param @param location 
  23.      * @param @return 
  24.      * @return View 
  25.      * @throws 
  26.      */ 
  27.     private View addViewToAnimLayout(final ViewGroup vg, final View view, int[] location){ 
  28.         int x = location[0]; 
  29.         int y = location[1]; 
  30.         vg.addView(view); 
  31.         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
  32.         lp.leftMargin = x; 
  33.         lp.topMargin = y; 
  34.         view.setLayoutParams(lp); 
  35.         return view; 
  36.     } 

这两个方法上面都有注释了。不细说了,一个是创建动画层,一个是添加要展示动画的视图组件到动画层上面。

第二步 (在Activity的onCreate 事件最后调用创建动画层)

 
  1. private ViewGroup anim_mask_layout;
     
  2. anim_mask_layout = createAnimLayout(); 

第三步 (针对具体组件实现动画效果)

 
  1. ImageView cartView = (ImageView) findViewById(R.id.btn_drug_detail_cart); 
  2.                     Button rightBtn = (Button) findViewById(R.id.right_btn); 
  3.                      
  4.                     int[] start_location = new int[2]; 
  5.                     cartView.getLocationInWindow(start_location); 
  6.                     int width = cartView.getWidth(); 
  7.                     int height = cartView.getHeight(); 
  8.                     ViewGroup vg = (ViewGroup)cartView.getParent(); 
  9.                     vg.removeView(cartView);
  10. //将组件添加到我们的动画层上
  11.                     View view = addViewToAnimLayout(anim_mask_layout, cartView, start_location); 
  12.                      
  13.                     int[] end_location = new int[2]; 
  14.                     rightBtn.getLocationInWindow(end_location); 
  15. //计算位移
  16.                     int endX = end_location[0]; 
  17.                     int endY = end_location[1] - start_location[1]; 
  18.                     Logger.i("endX:"+endX+",endY"+endY); 
  19.                     Animation mTranslateAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endX, TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endY);// 移动 
  20.                     mTranslateAnimation.setDuration(3000); 
  21.                     AnimationSet mAnimationSet=new AnimationSet(false); 
  22. //这块要注意,必须设为false,不然组件动画结束后,不会归位。
  23.                     mAnimationSet.setFillAfter(false); 
  24.                     mAnimationSet.addAnimation(mTranslateAnimation); 
  25.                     view.startAnimation(mAnimationSet); 

到此就完成了。动画那块代码其实还可以做些封装。直接view.startAnim(传动画集对象);

上面的方法。是与当前页面的布局和程序,没有一丝 的。这样就可以在需要的页面直接调用。也可以做应用全局的动画实现方案。

附件有整理好的源码Demo

第一次写博文。写得好,大家多顶一哈。