2013-04-13 67 views
1

我創建了一個視圖,該視圖具有佔據屏幕頂部1/3的MapFragment和佔據屏幕底部2/3的ListView。 ListView在列表項的正上方有一個「句柄」,用戶可以用它來上下拖動整個ListView。一旦用戶將手指從屏幕上釋放,ListView應該動畫到整個屏幕的最上面或最下面的邊框。到目前爲止,我的工作已經開始,但動畫並不平坦。在用戶從屏幕上鬆開手指後,在ListView開始向最近邊緣開始動畫之前,會出現明顯的暫停。我正在使用ObjectAnimator的nineoldandroids實現,以便動畫可以在蜂窩前設備上工作。有任何想法嗎?如何使用ObjectAnimator基於拖動來平滑地上/下視圖動畫?

這裏是我下面的onTouch IMPL:

public boolean onTouch(View v, MotionEvent event) { 
    final LayoutParams listLp = (LayoutParams) mListFrame.getLayoutParams(); 
    final int topMargin = -mHandleShadow.getHeight(); 
    final int middleMargin = getResources().getDimensionPixelSize(R.dimen.map_handle_margin_top); 
    final int bottomMargin = getView().getHeight() - mHandle.getHeight() - mHandleShadow.getHeight(); 

    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      mInitY = (int) event.getRawY(); 
      mTopMargin = listLp.topMargin; 

      break; 
     case MotionEvent.ACTION_MOVE: 
      int y = mTopMargin + (int) event.getRawY() - mInitY; 

      if (y >= -mHandleShadow.getHeight() && y <= (mViewHeight - mHandle.getHeight() - mHandleShadow.getHeight())) { 
       listLp.topMargin = y; 
       mListFrame.setLayoutParams(listLp); 
      } 

      break; 
     case MotionEvent.ACTION_UP: 
      if ((mInitY > event.getRawY() && mClosestAnchor == Anchor.MIDDLE) || (listLp.topMargin < middleMargin && mClosestAnchor == Anchor.BOTTOM)) { 
       ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", topMargin); 
       animator.setInterpolator(new AccelerateInterpolator()); 
       animator.start(); 

       mClosestAnchor = Anchor.TOP; 
      } 
      else if ((mInitY < event.getRawY() && mClosestAnchor == Anchor.MIDDLE) || (listLp.topMargin > middleMargin && mClosestAnchor == Anchor.TOP)) { 
       ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", bottomMargin); 
       animator.setInterpolator(new AccelerateInterpolator()); 
       animator.start(); 

       mClosestAnchor = Anchor.BOTTOM; 
      } 
      else { 
       ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", middleMargin); 
       animator.setInterpolator(new AccelerateInterpolator()); 
       animator.start(); 

       mClosestAnchor = Anchor.MIDDLE; 
      } 

      break; 
    } 

    return true; 
} 

回答

8

最後解決了該問題讀谷歌的切特·哈澤的答案,在這裏發現了類似的問題後。 https://stackoverflow.com/a/14780019/476005

在每一幀上調整視圖邊距太昂貴,並且一直會停頓,除非您移動的視圖非常簡單。因此,要解決這個問題,我在我的OnTouch(...)方法如下:

  1. 在MotionEvent.ACTION_DOWN:設置視圖的高度,它的最大高度。
  2. 在MotionEvent.ACTION_MOVE:用0
  3. 的持續時間在MotionEvent.ACTION_UP動畫視圖的「Y」屬性設置event.getRawY:動畫視圖的「Y」屬性視圖的父母的優勢之一。這裏要做的重要事情是在onAnimationEnd中適當地設置View的高度。

我希望這可以幫助大家。

+1

爲什麼不在ACTION_MOVE上使用setY? –