ViewPager禁用滑动到某个方向

Won*_*abo 17 android swipe android-viewpager

我想禁用滑动,但仅限于右侧.我发现在工作液这个答案.不幸的是,这复制了整个ViewPager源以实现目标.是否有任何方法只是继承现有的类而不是重复?

Avi*_*Mor 22

我不确定这正是你所需要的:我需要一个viewpager用于一个具有最大页面的向导,用户无法通过它.

最后,解决方案在适配器中.我改变了PagerAdapter的计数,这样就阻止了用户传递最大页面:

@Override
public int getCount() {
    return mProgress; //max page + 1
}
Run Code Online (Sandbox Code Playgroud)

当用户进入下一页时:

private void setWizardProgress(int progress) {
    if(progress > mProgress) {
        mProgress = progress;
        mWizardPagerAdapter.notifyDataSetChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,当用户处于最大页面时,他无法向右滚动.

  • 谢谢!这是一个老问题,我已经解决了这个问题(通过删除`ViewPager` 并使用`Fragment` 动画,这样我就可以完全控制流程)。我认为你是一个很好的解决方案,所以我接受它。:) (2认同)

and*_*9mv 20

这是工作ViewPager类,可以禁用任何方向分页.在这里查看所有答案.

public class CustomViewPager extends ViewPager {
    private float initialXValue;
    private SwipeDirection direction;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.direction = SwipeDirection.all;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.IsSwipeAllowed(event)) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.IsSwipeAllowed(event)) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    private boolean IsSwipeAllowed(MotionEvent event) {
        if(this.direction == SwipeDirection.all) return true;

        if(direction == SwipeDirection.none )//disable any swipe
            return false;

        if(event.getAction()==MotionEvent.ACTION_DOWN) {
            initialXValue = event.getX();
            return true;
        }

        if(event.getAction()==MotionEvent.ACTION_MOVE) {
            try {
                float diffX = event.getX() - initialXValue;
                if (diffX > 0 && direction == SwipeDirection.right ) {
                    // swipe from left to right detected
                    return false;
                }else if (diffX < 0 && direction == SwipeDirection.left ) {
                    // swipe from right to left detected
                    return false;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }

        return true;
    }

    public void setAllowedSwipeDirection(SwipeDirection direction) {
        this.direction = direction;
    }
Run Code Online (Sandbox Code Playgroud)

  • try-catch 块是不必要的。它里面的任何东西都不会抛出异常。 (2认同)

jwB*_*ide 9

另一种简单的方法是使用setCurrentItem()在您到达某个位置时滚动回所需的幻灯片.例如,这只允许向前滑动:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {
        if(position < mProgress) {
            mViewPager.setCurrentItem(mProgress, true);
        } else {
            mProgress = position;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {}
});
Run Code Online (Sandbox Code Playgroud)

或者,如果您想要最大幻灯片:

if(position > 4) {
    mViewPager.setCurrentItem(4, true);
}
Run Code Online (Sandbox Code Playgroud)

此解决方案在技术上不会完全禁用滑动,因为当您进行滑动移动时,您仍会看到一小部分不允许的滑动.但对于某些应用,这可能是首选.


Rit*_*une 5

您可以尝试以下方法:

第1步:创建一个新的自定义类说" CustomViewPager".该类继承自" ViewPager"并包含一个名为" setPagingEnabled" 的新自定义方法,其目的是根据需要启用/禁用滑动.

第2步:覆盖两种方法:" onTouchEvent"和" onInterceptTouchEvent".false如果要完全禁用分页,则两者都将返回" ".

第3步:ViewPager使用自定义类替换布局文件中的" "标记:

    <package_name.customviewpager 
     android:id="@+id/customViewPager" 
     android:layout_height="match_parent" 
     android:layout_width="match_parent" />
Run Code Online (Sandbox Code Playgroud)

第4步: CustomViewPager.java

    public class CustomViewPager extends ViewPager {

private boolean enabled;

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled && detectSwipeToRight(event)) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled && detectSwipeToRight(event)) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

// To enable/disable swipe 
public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
}

// Detects the direction of swipe. Right or left. 
// Returns true if swipe is in right direction
public boolean detectSwipeToRight(MotionEvent event){

 int initialXValue = 0; // as we have to detect swipe to right
 final int SWIPE_THRESHOLD = 100; // detect swipe
 boolean result = false;

        try {                
            float diffX = event.getX() - initialXValue;

                if (Math.abs(diffX) > SWIPE_THRESHOLD ) {
                    if (diffX > 0) {
                        // swipe from left to right detected ie.SwipeRight
                        result = false;
                    } else {
                        // swipe from right to left detected ie.SwipeLeft
                        result = true;
                    }
                }
            } 
         catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了更新的答案.`diffX`总是正数,因此该方法永远不会返回`true`. (5认同)