Answers:
一个简单的解决方案是创建自己的ViewPager
带有private boolean
标记的子类isPagingEnabled
。然后覆盖onTouchEvent
和onInterceptTouchEvent
方法。如果为isPagingEnabled
true,则调用该super
方法,否则为return
。
public class CustomViewPager extends ViewPager {
private boolean isPagingEnabled = true;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onInterceptTouchEvent(event);
}
public void setPagingEnabled(boolean b) {
this.isPagingEnabled = b;
}
}
然后在Layout.XML
文件<com.android.support.V4.ViewPager>
中用<com.yourpackage.CustomViewPager>
标签替换所有标签。
此代码改编自此博客文章。
有一个简单的解决方法:
当您想禁用viewpager滚动时,请执行以下操作:
mViewPager.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
return true;
}
});
而当您想重新启用它时:
mViewPager.setOnTouchListener(null);
这样就可以了。
这是我对Slayton的回答的轻量型变体:
public class DeactivatableViewPager extends ViewPager {
public DeactivatableViewPager(Context context) {
super(context);
}
public DeactivatableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return !isEnabled() || super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return isEnabled() && super.onInterceptTouchEvent(event);
}
}
使用我的代码,您可以使用禁用分页setEnable()
。
onInterceptTouchEvent()
将阻止子视图接收输入。在大多数情况下,这不是预期的行为。
我找到了一个简单的解决方案。
//disable swiping
mViewPager.beginFakeDrag();
//enable swiping
mViewPager.endFakeDrag();
我建议另一种解决此问题的方法。这个想法是通过scrollView包裹viewPager,以便当该scrollView不可滚动时,您的viewPager也是不可滚动的。
这是我的XML布局:
<HorizontalScrollView
android:id="@+id/horizontalScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</HorizontalScrollView>
无需代码。
对我来说很好。
最适合我的解决方案是:
public class DeactivatedViewPager extends ViewPager {
public DeactivatedViewPager (Context context) {
super(context);
}
public DeactivatedViewPager (Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean canScrollHorizontally(int direction) {
return false;
}
}
此后,将通过触摸禁用滚动,然后您仍然可以使用setCurrentItem
方法更改页面。
canScrollHorizontally()
方法在当前情况下无效。滑动时甚至不会调用它。
这是Kotlin和androidX的答案
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager
class DeactivatedViewPager @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : ViewPager(context, attrs) {
var isPagingEnabled = true
override fun onTouchEvent(ev: MotionEvent?): Boolean {
return isPagingEnabled && super.onTouchEvent(ev)
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return isPagingEnabled && super.onInterceptTouchEvent(ev)
}
}
怎么样:
我使用了CustomViewPager
,接下来,重写了scrollTo方法
,当我进行许多小滑动时,我检查了运动,它不会滚动到其他页面。
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) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public void scrollTo(int x, int y) {
if(enabled) {
super.scrollTo(x, y);
}
}
}
View.scrollTo(int x, int y)
为我解决了这个问题。 感谢
在我使用ViewPager 2 alpha 2的情况下,以下代码段有效
viewPager.isUserInputEnabled = false
能够禁用用户输入(setUserInputEnabled,isUserInputEnabled)
请参阅此以在viewpager2 1.0.0-alpha02中进行更多更改
还对最新版本ViewPager 2 alpha 4进行了一些更改。
方向和isUserScrollable属性不再是SavedState的一部分
请参阅此以获取viewpager2#1.0.0-alpha04中的更多更改
斯莱顿的答案很好。如果您想像猴子一样停止滑动,可以使用以下方法覆盖OnPageChangeListener
@Override public void onPageScrollStateChanged(final int state) {
switch (state) {
case ViewPager.SCROLL_STATE_SETTLING:
mPager.setPagingEnabled(false);
break;
case ViewPager.SCROLL_STATE_IDLE:
mPager.setPagingEnabled(true);
break;
}
}
所以你只能并排滑动
setPagingEnabled()
方法的作用。请提供完整的代码。
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;
public class NonSwipeableViewPager extends ViewPager {
public NonSwipeableViewPager(Context context) {
super(context);
}
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// stop swipe
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// stop switching pages
return false;
}
private void setMyScroller() {
try {
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
scroller.set(this, new MyScroller(getContext()));
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyScroller extends Scroller {
public MyScroller(Context context) {
super(context, new DecelerateInterpolator());
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int
duration) {
super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
}
}
}
然后在Layout.XML文件中,将--com.android.support.V4.ViewPager ---标记替换为--- com.yourpackage.NonSwipeableViewPager ---标记。