我想禁用滑动,但仅限于右侧。我在this回答中找到了一个有效的解决方案。不幸的是,这会复制整个ViewPager
来源以实现目标。是否有任何方法只是继承现有的类而不是重复?
答案 0 :(得分:23)
我不确定这正是你所需要的: 我需要一个viewpager用于具有最大页面的向导,用户无法通过该页面。
最后解决方案在适配器中。 我更改了PagerAdapter的计数,这样就阻止了用户传递最大页面:
@Override
public int getCount() {
return mProgress; //max page + 1
}
当用户进入下一页时:
private void setWizardProgress(int progress) {
if(progress > mProgress) {
mProgress = progress;
mWizardPagerAdapter.notifyDataSetChanged();
}
}
这样,当用户处于最大页面时,他无法向右滚动。
答案 1 :(得分:19)
这是一个可以禁用任何方向分页的ViewPager类。 查看所有answer here 。
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;
}
答案 2 :(得分:8)
另一种简单的方法是使用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) {}
});
或者如果您想要最大幻灯片:
if(position > 4) {
mViewPager.setCurrentItem(4, true);
}
此解决方案在技术上不会完全禁用滑动,因为当您进行滑动移动时,您仍然会看到一小部分不允许的滑动。但对于某些应用,这可能是首选。
答案 3 :(得分: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" />
第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;
}
}
答案 4 :(得分:1)
private float initialXValue;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.mEnabled) {
return super.onTouchEvent(event);
}
if(event.getAction()==MotionEvent.ACTION_DOWN){
initialXValue = event.getX();
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
if(detectSwipeToRight(event)){
System.out.println("right swipe detected");
}
}
return true;
}
private boolean detectSwipeToRight(MotionEvent event) {
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 right to left detected ie.SwipeLeft
result = true;
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
答案 5 :(得分:1)
您可以使用方法beginFakeDrag()
和endFakeDrag()
。
beginFakeDrag()
当你想要禁用滑动时
如果您想再次启用,请endFakeDrag()
。
像这样:viewPager.beginFakeDrag();
答案 6 :(得分:-2)
您必须创建自己的ViewPager子类并覆盖canScrollHorizontally函数