7

我目前在ViewPager中水平排列了Views,並且可以通過PagerAdapter循環瀏覽它們。目前,要執行我想要在滑動時執行的操作,我必須在視圖的頁面上雙擊。我可以發佈代碼,但它很難提取必要的作品...實現像iOS應用程序垂直關閉的功能使用ViewPager滑動即可關閉

我想要的是能夠在這些視圖上垂直滑動,讓他們垂直翻轉並輕掃和淡出,然後執行當它們距離設備邊緣一定距離時動作。

要了解我的想法,請在Gallery應用程序中捏住已打開的照片以縮小並打開水平幻燈片視圖。從那裏你可以向上(或向下)上的照片/視頻刪除它。對於那些沒有相同圖庫應用程序的人來說,這就像在iOS上關閉應用程序一樣。

我試過掃描雖然畫廊應用程序的源代碼,但沒有找到正確的活動運氣。

回答

3

我最終得到這個克隆的工作更多或更少寫得很好的Android-SwipeToDismiss庫,並用ViewPager代替ListView代碼。

成品看起來像這樣。

end result

+0

你可以發佈你已經實現viewpager的代碼嗎? –

+0

正如我在問題中所述,提取最小代碼示例很困難。有5個類和2個接口涉及。我已經提供了鏈接到庫和修改ListView示例使用ViewPager很簡單(在我看來) –

+0

所以你的意思是我只需要用ViewPager替換ListView,它會工作? –

4
view.setOnTouchListener(new View.OnTouchListener(){ 
    public boolean onTouch(View v, MotionEvent motion) { 
     float y = motion.getY(); 
     /* NOTE: the following line might need to be in runOnUiThread() */ 
     view.animate().alpha(1-Math.abs(y-height/2)/(height/2)).setDuration(50).start(); 
     return true; //false if you want to pass this event on to other listeners 
    } 
}); 

使用1-Math.abs(y-height/2)/(height/2)的解釋是,我想的α爲1,當我在中心,和α是0時,它是在頂部或底部。您必須確定自己如何獲得height值,或者如果您想使用其他方法計算alpha。如果您想要獲取相對於屏幕的觸摸位置,而不是相對於視圖的位置,請使用getRawY()

此外,它可能是有用的,你知道,看是否MotionEvent是一按,拖動,或釋放事件,請使用 motion.getAction() ==與MotionEvent.ACTION_UP,MotionEvent.ACTION_MOVE和MotionEvent.ACTION_DOWN,分別。

+0

如果我想在alpha中的位置變化而不是持續的變化?我希望這個視圖能夠在它原來的位置或它正在滑向的邊緣上消失。 –

+0

已更新代碼以反映此情況。不再使用手勢。 – geokavel

+0

好的,那麼在ViewPager中翻譯視圖時如何轉換視圖?它看起來像這個代碼只是基於觸摸位置淡化視圖。 –

1

檢查下面的代碼,這可能對您有所幫助:

public class MainActivity extends Activity implements View.OnTouchListener{ 

    private RelativeLayout baseLayout; 

    private int previousFingerPosition = 0; 
    private int baseLayoutPosition = 0; 
    private int defaultViewHeight; 

    private boolean isClosing = false; 
    private boolean isScrollingUp = false; 
    private boolean isScrollingDown = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_popup); 
     baseLayout = (RelativeLayout) findViewById(R.id.base_popup_layout);//this is the main layout 
     baseLayout.setOnTouchListener(this); 
    } 


    public boolean onTouch(View view, MotionEvent event) { 

     // Get finger position on screen 
     final int Y = (int) event.getRawY(); 

     // Switch on motion event type 
     switch (event.getAction() & MotionEvent.ACTION_MASK) { 

      case MotionEvent.ACTION_DOWN: 
       // save default base layout height 
       defaultViewHeight = baseLayout.getHeight(); 

       // Init finger and view position 
       previousFingerPosition = Y; 
       baseLayoutPosition = (int) baseLayout.getY(); 
       break; 

      case MotionEvent.ACTION_UP: 
       // If user was doing a scroll up 
       if(isScrollingUp){ 
        // Reset baselayout position 
        baseLayout.setY(0); 
        // We are not in scrolling up mode anymore 
        isScrollingUp = false; 
       } 

       // If user was doing a scroll down 
       if(isScrollingDown){ 
        // Reset baselayout position 
        baseLayout.setY(0); 
        // Reset base layout size 
        baseLayout.getLayoutParams().height = defaultViewHeight; 
        baseLayout.requestLayout(); 
        // We are not in scrolling down mode anymore 
        isScrollingDown = false; 
       } 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if(!isClosing){ 
        int currentYPosition = (int) baseLayout.getY(); 

        // If we scroll up 
        if(previousFingerPosition >Y){ 
         // First time android rise an event for "up" move 
         if(!isScrollingUp){ 
          isScrollingUp = true; 
         } 

        // Has user scroll down before -> view is smaller than it's default size -> resize it instead of change it position 
        if(baseLayout.getHeight()<defaultViewHeight){ 
         baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition); 
         baseLayout.requestLayout(); 
        } 
        else { 
         // Has user scroll enough to "auto close" popup ? 
         if ((baseLayoutPosition - currentYPosition) > defaultViewHeight/4) { 
          closeUpAndDismissDialog(currentYPosition); 
          return true; 
         } 

         // 
        } 
        baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition)); 

       } 
       // If we scroll down 
       else{ 

        // First time android rise an event for "down" move 
        if(!isScrollingDown){ 
         isScrollingDown = true; 
        } 

        // Has user scroll enough to "auto close" popup ? 
        if (Math.abs(baseLayoutPosition - currentYPosition) > defaultViewHeight/2) 
        { 
         closeDownAndDismissDialog(currentYPosition); 
         return true; 
        } 

        // Change base layout size and position (must change position because view anchor is top left corner) 
        baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition)); 
        baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition); 
        baseLayout.requestLayout(); 
       } 

       // Update position 
       previousFingerPosition = Y; 
      } 
      break; 
     } 
     return true; 
    } 
} 

對於動畫使用下面的方法:

public void closeUpAndDismissDialog(int currentPosition){ 
    isClosing = true; 
    ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, -baseLayout.getHeight()); 
    positionAnimator.setDuration(300); 
    positionAnimator.addListener(new Animator.AnimatorListener() 
    { 
     . . . 
     @Override 
     public void onAnimationEnd(Animator animator) 
     { 
      finish(); 
     } 
     . . . 
    }); 
    positionAnimator.start(); 
} 

public void closeDownAndDismissDialog(int currentPosition){ 
    isClosing = true; 
    Display display = getWindowManager().getDefaultDisplay(); 
    Point size = new Point(); 
    display.getSize(size); 
    int screenHeight = size.y; 
    ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, screenHeight+baseLayout.getHeight()); 
    positionAnimator.setDuration(300); 
    positionAnimator.addListener(new Animator.AnimatorListener() 
    { 
     . . . 
     @Override 
     public void onAnimationEnd(Animator animator) 
     { 
      finish(); 
     } 
     . . . 
    }); 
    positionAnimator.start(); 
} 
+0

我猜baseLayout可以是ViewPager而不是LinearLayout?另外,如果我正在嘗試執行此操作的ViewPager位於片段內,那麼它會起作用嗎? –

+0

baseLayout是xml佈局中的根父視圖 –

+0

我不希望整個Activity移動,只是ViewPager當前顯示的單個視圖。 –

相關問題