最近给自已负责的项目里,个别交互增加了一些动画效果。发现了一个很常见的动画效果问题。
问题描述
蓝色框包含的区域是一个停靠在页面底部的浮动菜单。当用户点了左边购物车按钮时,要用一个动画效果:购物车图标从当前位置 滑动到 页面右上角的一个查看购物车按钮上。
一般的实现思路:
这里假设 购物车View 对象为 cartView;页面右上角的 View对象为 rightBtn;
- ImageView cartView = (ImageView) findViewById(R.id.btn_drug_detail_cart);
- Button rightBtn = (Button) findViewById(R.id.right_btn);
- int[] start_location = new int[2];
- cartView.getLocationInWindow(start_location);
- int[] end_location = new int[2];
- rightBtn.getLocationInWindow(end_location);
- int endX = end_location[0];
- int endY = end_location[1] - start_location[1];
- Logger.i("endX:"+endX+",endY"+endY);
- Animation mTranslateAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endX, TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endY);// 移动
- mTranslateAnimation.setDuration(3000);
- AnimationSet mAnimationSet=new AnimationSet(false);
- mAnimationSet.setFillAfter(true);
- mAnimationSet.addAnimation(mTranslateAnimation);
- view.startAnimation(mAnimationSet);
在购物车的单击事件里执行此动画代码,发现 购物车图标是移动了,当移出蓝色区域边框时,消失了。
下面给出页面某小块区域内的组件想要在整个页面滑动的动画效果 实现方法:
原理:
Android Activity视窗根布局是 FrameLayout.我们可以在根布局上面添加我们的动画效果层。然后要想移某一个组件,先把该组件从原父容器移除,再移到我们的动画层里,然后效果展示。需要注意
1.动画层背景为透明
2.动画层不要绑定事件,不然会影响下面的视图获取事件(一般来说动画层也不会提供用户交互)
给出实现代码:
第一步: (创建我们需要的一些方法)
- /**
- * @Description: 创建动画层
- * @param
- * @return void
- * @throws
- */
- private ViewGroup createAnimLayout(){
- ViewGroup rootView = (ViewGroup)this.getWindow().getDecorView();
- LinearLayout animLayout = new LinearLayout(this);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
- animLayout.setLayoutParams(lp);
- animLayout.setId(R.id.anim_mask_layout);
- animLayout.setBackgroundResource(android.R.color.transparent);
- rootView.addView(animLayout);
- return animLayout;
- }
- /**
- * @Description: 添加视图到动画层
- * @param @param vg
- * @param @param view
- * @param @param location
- * @param @return
- * @return View
- * @throws
- */
- private View addViewToAnimLayout(final ViewGroup vg, final View view, int[] location){
- int x = location[0];
- int y = location[1];
- vg.addView(view);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
- lp.leftMargin = x;
- lp.topMargin = y;
- view.setLayoutParams(lp);
- return view;
- }
这两个方法上面都有注释了。不细说了,一个是创建动画层,一个是添加要展示动画的视图组件到动画层上面。
第二步 (在Activity的onCreate 事件最后调用创建动画层)
- private ViewGroup anim_mask_layout;
- anim_mask_layout = createAnimLayout();
第三步 (针对具体组件实现动画效果)
- ImageView cartView = (ImageView) findViewById(R.id.btn_drug_detail_cart);
- Button rightBtn = (Button) findViewById(R.id.right_btn);
- int[] start_location = new int[2];
- cartView.getLocationInWindow(start_location);
- int width = cartView.getWidth();
- int height = cartView.getHeight();
- ViewGroup vg = (ViewGroup)cartView.getParent();
- vg.removeView(cartView);
- //将组件添加到我们的动画层上
- View view = addViewToAnimLayout(anim_mask_layout, cartView, start_location);
- int[] end_location = new int[2];
- rightBtn.getLocationInWindow(end_location);
- //计算位移
- int endX = end_location[0];
- int endY = end_location[1] - start_location[1];
- Logger.i("endX:"+endX+",endY"+endY);
- Animation mTranslateAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endX, TranslateAnimation.RELATIVE_TO_SELF, 0.0f, TranslateAnimation.ABSOLUTE, endY);// 移动
- mTranslateAnimation.setDuration(3000);
- AnimationSet mAnimationSet=new AnimationSet(false);
- //这块要注意,必须设为false,不然组件动画结束后,不会归位。
- mAnimationSet.setFillAfter(false);
- mAnimationSet.addAnimation(mTranslateAnimation);
- view.startAnimation(mAnimationSet);
到此就完成了。动画那块代码其实还可以做些封装。直接view.startAnim(传动画集对象);
上面的方法。是与当前页面的布局和程序,没有一丝 的。这样就可以在需要的页面直接调用。也可以做应用全局的动画实现方案。
附件有整理好的源码Demo
第一次写博文。写得好,大家多顶一哈。