由於預設情況下,動畫只針對當前父布局範圍中有效,有的時候我們需要在全屏範圍中做做飄的效果;實際做法我想應該有兩個:
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() {@Overridepublic void onAnimationStart(Animation animation) {fromView.setVisibility(View.INVISIBLE);}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {newView.setVisibility(View.GONE);//動畫結束後做某些操作handler.post(new Runnable() {@Overridepublic 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;@Overridepublic 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);}@Overrideprotected 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);}@Overridepublic void initialize(int width, int height, int parentWidth, int parentHeight) {super.initialize(width, height, parentWidth, parentHeight);}}