使用ViewPager实现iOS应用程序关闭垂直Swipe-to-Dismiss等功能

时间:2015-10-15 21:51:50

标签: android android-fragments android-viewpager fragmentpageradapter swipe-gesture

我目前在ViewPager中水平排列了视图,并且可以使用PagerAdapter循环浏览它们。目前,要执行我想要在滑动上执行的操作,我必须在“查看”页面上双击。我可以发布代码,但提取必要的部分有点困难......

我想要的是能够在这些视图上垂直滑动,让它们通过滑动和淡出垂直平移,然后在距离设备边缘一定距离时执行操作。

要了解我的想法,在Gallery应用中,您可以捏开已打开的照片以缩小并打开水平幻灯片视图。在那里,您可以向上(或向下)扫描照片/视频以删除它。对于那些没有相同Gallery应用程序的用户,它就像在iOS上关闭应用程序一样。

我已尝试扫描图库应用的源代码,但没有找到正确的活动。

3 个答案:

答案 0 :(得分: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)的解释是,当我在中心时,我希望alpha为1,当它位于顶部或底部时,alpha为0。您必须自己确定如何获得height值,或者如果您想使用其他方法来计算alpha。如果要获得相对于屏幕的触摸位置而不是相对于视图的位置,请使用getRawY()

此外,了解MotionEvent是按下,拖动还是释放事件可能对您有用,请使用 motion.getAction() ==分别包含MotionEvent.ACTION_UP,MotionEvent.ACTION_MOVE和MotionEvent.ACTION_DOWN。

答案 1 :(得分:4)

我最终通过克隆编写良好的Android-SwipeToDismiss库并使用ViewPager替换ListView代码来获得或多或少的工作。

成品看起来像这样。

end result

答案 2 :(得分: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();
}