由于默认情况下,动画只针对当前父布局范围中有效,有的时候我们需要在全屏范围中做做飘的效果;实际做法我想应该有两个:
1. 用绝对坐标的方式执行动画
设置动画时设置类型为绝对位置执行。
2. 使用中间控件模拟,此中间控件为与setContenView中view同级,然后计算出移动位置进行动画
通过view.getParent()得到ViewGroup,然后给ViewGroup.addView(中间控件),再给中间控件做动画。
提示:
getLocalVisibleRect , 返回一个填充的Rect对象,Android获取view在屏幕中的位置, 感觉是这个View的Rect大小,left,y值,//获取在整个窗口内的绝对坐标getLeft , getTop, getBottom, getRight, 这一组是获取相对在
getLocalVisibleRect , 返回一个填充的Rect对象, 感觉是这个View的Rect大小,left,top取到的都是0
getGlobalVisibleRect , 获取全局坐标系的一个视图区域, 返回一个填充的Rect对象;该Rect是基于总整个屏幕的
getLocationOnScreen ,计算该视图在全局坐标系中的x,y值,(注意这个值是要从屏幕顶端算起,也就是索包括了通知栏的高度)//获取在当前屏幕内的绝对坐标
getLocationInWindow ,计算该视图在它所在的widnow的坐标x,y值,//获取在整个窗口内的绝对坐标
getLeft , getTop, getBottom, getRight, 这一组是获取相对在它父亲里的坐标
本文中两者结合着使用,代码如下:
private void beginAnimationAndRefresh(final View fromView, final boolean isBack) { final ViewGroup parent = (ViewGroup) view.getParent();//view为当前setContentview中的参数 final DailyDateView newView = new DailyDateView(Activity.this);//可以用自己定义的View,创建一个新的view作为中间view去执行动画 newView.setLayoutParams(fromView.getLayoutParams()); final AnimationListener listener = new AnimationListener() { @Override public void onAnimationStart(Animation animation) { fromView.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { newView.setVisibility(View.GONE);//动画结束后做某些操作 handler.post(new Runnable() { @Override public void run() { parent.removeView(newView); if (isBack) { dateWeekView.setDailyViewShow(); setShowSiderView(false); } } }); } }; handler.post(new Runnable() { private AnimationSet animation = new AnimationSet(true); private DailyViewAnimation translateAnim; private AlphaAnimation alphaAnim; private Rect fromRect; private Rect toRect; private Rect stateR; private int startX; private int startY; private int endX; private int endY; private float startAlpha; private float endAlpha; @Override public void run() { parent.addView(newView, fromView.getWidth(), fromView.getHeight()); if (isBack) { View toView = dateWeekView.getDailyView(); fromRect = JingoalDisplayUtil.getGlobalRect(fromView); toRect = JingoalDisplayUtil.getGlobalRect(toView); stateR = JingoalDisplayUtil.getStateBarRect(toView); startX = fromRect.left; startY = fromRect.top - stateR.top; endX = toRect.left; endY = toRect.top - stateR.top; startAlpha = 1f; endAlpha = 0.5f; } else { View toItemView = gridView.getChildAt(2); fromRect = JingoalDisplayUtil.getGlobalRect(fromView); toRect = JingoalDisplayUtil.getGlobalRect(toItemView); stateR = JingoalDisplayUtil.getStateBarRect(toItemView); startX = fromRect.left; startY = fromRect.top; endX = toRect.left; endY = toRect.top - stateR.top; startAlpha = 0.6f; endAlpha = 1f; } translateAnim = new DailyViewAnimation(Animation.ABSOLUTE, Animation.ABSOLUTE, startX, endX, startY, endY); alphaAnim = new AlphaAnimation(startAlpha, endAlpha); animation.addAnimation(translateAnim); animation.addAnimation(alphaAnim); newView.setAnimation(animation); animation.setDuration(300); animation.setAnimationListener(listener); animation.start(); } });
public class DisplayUtil { static Rect rect; /* * 状态栏高度 View的getWindowVisibleDisplayFrame(Rect outRect)附值outRect后,outRect.top()即是状态栏高度 * 标题高度 View的getWindowVisibleDisplayFrame(Rect outRect1)附值outRect后,outRect.height()-view.getheight()即是标题高度。 */ public static Rect getStateBarRect(View v) { rect = new Rect(); v.getWindowVisibleDisplayFrame(rect); return rect; } public static Rect getGlobalRect(View v) { rect = new Rect(); v.getGlobalVisibleRect(rect);//取出view在全屏中显示的坐标 return rect; } }
public class DailyViewAnimation extends TranslateAnimation { public DailyViewAnimation(int fromType, int toType, float fromXValue, float toXValue, float fromYValue, float toYValue) { super(fromType, fromXValue, toType, toXValue, fromType, fromYValue, toType, toYValue); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { // int newHeight; // if (this.initiallyCollapsed) { // newHeight = (int) (this.deltaY * interpolatedTime); // } else { // newHeight = (int) (this.deltaY * (1 - interpolatedTime)); // } // view.getLayoutParams().height = newHeight; // view.requestLayout(); super.applyTransformation(interpolatedTime, t); } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); } }