我有ViewPager
实例化View
。当搜索结果返回到视图时,我想暂时禁用viewpager和子按钮的滚动。我打电话给viewPager.setEnabled(false)
,但这并没有禁用它。
有人有任何想法吗?
答案 0 :(得分:336)
一个简单的解决方案是创建自己的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>
个代码。
此代码改编自此blog post。
答案 1 :(得分:33)
这个有一个简单的解决方法:
如果要禁用viewpager滚动,请执行以下操作:
mViewPager.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
return true;
}
});
如果你想重新启用它,那么:
mViewPager.setOnTouchListener(null);
这样就可以了。
答案 2 :(得分:28)
这是我对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()
停用分页。
答案 3 :(得分:19)
我找到了一个简单的解决方案。
//disable swiping
mViewPager.beginFakeDrag();
//enable swiping
mViewPager.endFakeDrag();
答案 4 :(得分:8)
我建议另一种方法来解决这个问题。我们的想法是用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>
无需代码。
对我来说很好。
答案 5 :(得分:5)
禁用滑动
mViewPager.beginFakeDrag();
启用滑动
mViewPager.endFakeDrag();
答案 6 :(得分:4)
对我有用的最佳解决方案是:
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
方法更改页面。
答案 7 :(得分:2)
这个怎么样:
我使用了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);
}
}
}
答案 8 :(得分:2)
这是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)
}
}
答案 9 :(得分:1)
slayton的答案很好。 如果你想像猴子一样停止滑动,你可以使用
覆盖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;
}
}
所以你只能并排滑动
答案 10 :(得分:1)
当您使用上面的答案时,您可能会遇到一个错误的问题:“将isScrollEnabled设置为false,此viewPager中的某些视图无法处理onClick和onTouchEvent。因此,我给出解决方案,希望它可以为您提供帮助...
class WrapContentViewPager @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) {
var isScrollEnabled = true
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
if(isScrollEnabled){
super.onInterceptTouchEvent(event)
}else{
return isScrollEnabled && super.onInterceptTouchEvent(event)
}
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
if(isScrollEnabled){
return isScrollEnabled
}else{
return isScrollEnabled && super.onTouchEvent(event)
}
}
}
答案 11 :(得分:1)
androidx中的新类ViewPager2允许使用setUserInputEnabled(false)方法禁用滚动
private val pager: ViewPager2 by bindView(R.id.pager)
override fun onCreate(savedInstanceState: Bundle?) {
pager.isUserInputEnabled = false
}
答案 12 :(得分:0)
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 ---标记的标签。
答案 13 :(得分:0)
在我使用ViewPager 2 alpha 2的情况下,以下代码段有效
viewPager.isUserInputEnabled = false
能够禁用用户输入(setUserInputEnabled,isUserInputEnabled)
请参阅此以获取viewpager2 1.0.0-alpha02
中的更多更改最新版本ViewPager 2 alpha 4也进行了一些更改
orientation和isUserScrollable属性不再是SavedState的一部分
请参阅此以获取viewpager2#1.0.0-alpha04
中的更多更改答案 14 :(得分:0)
我基于从Java转换以下答案创建了Kotlin版本:https://stackoverflow.com/a/13437997/8023278
没有内置的方法来禁用ViewPager页面之间的滑动,需要的是ViewPager的扩展,该扩展会覆盖onTouchEvent和onInterceptTouchEvent以防止滑动动作。为了使它更通用,我们可以添加一个setSwipePagingEnabled方法来启用/禁用页面之间的滑动。
class SwipeLockableViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
private var swipeEnabled = false
override fun onTouchEvent(event: MotionEvent): Boolean {
return when (swipeEnabled) {
true -> super.onTouchEvent(event)
false -> false
}
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return when (swipeEnabled) {
true -> super.onInterceptTouchEvent(event)
false -> false
}
}
fun setSwipePagingEnabled(swipeEnabled: Boolean) {
this.swipeEnabled = swipeEnabled
}
}
然后在布局XML中,使用新的SwipeLockableViewPager而不是标准ViewPager
<mypackage.SwipeLockableViewPager
android:id="@+id/myViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
现在在活动/片段中,我们可以呼叫myViewPager.setSwipePagingEnabled(false)
,而用户将无法在页面之间滑动
更新
截至2020年,我们现在有ViewPager2。如果您migrate到ViewPager2,则有一个内置的方法来禁止滑动:myViewPager2.isUserInputEnabled = false