the*_*ist 521 android android-viewpager
我有ViewPager,在它下面我有10个按钮.通过单击按钮,例如#4,寻呼机立即转到第4页mPager.setCurrentItem(3);.但是,我想通过水平手指滑动来禁用分页.因此,寻呼完成仅通过点击按钮.那么,我怎么能用手指禁用滑动?
lou*_*uie 864
你需要子类ViewPager. onTouchEvent有很多好东西,你不想改变,如允许儿童观点接触. onInterceptTouchEvent是你想要改变的.如果你查看代码ViewPager,你会看到评论:
/*
* This method JUST determines whether we want to intercept the motion.
* If we return true, onMotionEvent will be called and we do the actual
* scrolling there.
*/
Run Code Online (Sandbox Code Playgroud)
这是一个完整的解决方案:
首先,将此类添加到您的src文件夹:
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);
setMyScroller();
}
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setMyScroller();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
//down one is added for smooth scrolling
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*/);
}
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,请确保使用此类而不是ViewPager您可能指定的常规类android.support.v4.view.ViewPager.在您的布局文件中,您需要使用以下内容指定它:
<com.yourcompany.NonSwipeableViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
Run Code Online (Sandbox Code Playgroud)
这个特定的例子在a中LinearLayout并且意味着占据整个屏幕,这就是为什么layout_weight是1并且layout_height是0dp.
并且setMyScroller();方法是平滑过渡
Raj*_*jul 450
更一般的扩展ViewPager是创建一个SetPagingEnabled方法,以便我们可以动态启用和禁用分页.要启用/禁用滑动,只需要两种方法:onTouchEvent和onInterceptTouchEvent.如果禁用分页,则两者都将返回"false".
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后选择此项而不是XML中的内置viewpager
<mypackage.CustomViewPager
android:id="@+id/myViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
Run Code Online (Sandbox Code Playgroud)
您只需要调用setPagingEnabled方法,false用户将无法滑动到分页.
Way*_*yne 102
最简单的办法就是setOnTouchListener和回报true的ViewPager.
mPager.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
Pie*_*tro 57
最好声明它是可设置的,因此您可以从xml更改其属性:
private boolean swipeable;
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPager);
try {
swipeable = a.getBoolean(R.styleable.MyViewPager_swipeable, true);
} finally {
a.recycle();
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return swipeable ? super.onInterceptTouchEvent(event) : false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return swipeable ? super.onTouchEvent(event) : false;
}
Run Code Online (Sandbox Code Playgroud)
在您的values/attr.xml中:
<declare-styleable name="MyViewPager">
<attr name="swipeable" format="boolean" />
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)
以便您可以在布局xml中使用它:
<mypackage.MyViewPager
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/viewPager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:swipeable="false" />
Run Code Online (Sandbox Code Playgroud)
当然,您仍然可以拥有get/set属性.
sid*_*don 56
如果您将ViewPager本身放在另一个ViewPager中onTouchEvent,onInterceptTouchEvent则仅覆盖并且还不够.子ViewPager会从父ViewPager窃取水平滚动触摸事件,除非它位于其第一页/最后一页.
要使此设置正常工作,您还需要覆盖该canScrollHorizontally方法.
见LockableViewPager下面的实施.
public class LockableViewPager extends ViewPager {
private boolean swipeLocked;
public LockableViewPager(Context context) {
super(context);
}
public LockableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean getSwipeLocked() {
return swipeLocked;
}
public void setSwipeLocked(boolean swipeLocked) {
this.swipeLocked = swipeLocked;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return !swipeLocked && super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return !swipeLocked && super.onInterceptTouchEvent(event);
}
@Override
public boolean canScrollHorizontally(int direction) {
return !swipeLocked && super.canScrollHorizontally(direction);
}
}
Run Code Online (Sandbox Code Playgroud)
Gre*_*ase 32
如果从ViewPager扩展,则还必须覆盖executeKeyEvent @araks之前指示的内容
@Override
public boolean executeKeyEvent(KeyEvent event)
{
return isPagingEnabled ? super.executeKeyEvent(event) : false;
}
Run Code Online (Sandbox Code Playgroud)
因为某些设备(如Galaxy Tab 4 10')显示这些按钮,大多数设备从不显示它们:
小智 27
要禁用滑动
mViewPager.beginFakeDrag();
Run Code Online (Sandbox Code Playgroud)
启用滑动
mViewPager.endFakeDrag();
Run Code Online (Sandbox Code Playgroud)
Nil*_*hod 22
现在我们无需创建自定义 ViewPager
ViewPager2 android中可用的新名称视图
ViewPager2除了传统的水平寻呼外,还支持垂直寻呼。您可以ViewPager2通过设置元素的android:orientation属性来启用元素的垂直分页使用XML
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:orientation="vertical" />
Run Code Online (Sandbox Code Playgroud)
使用代码
禁用正在viewpager2使用的刷卡
viewPager2.setUserInputEnabled(false);
Run Code Online (Sandbox Code Playgroud)
在viewpager2使用中启用刷卡
viewPager2.setUserInputEnabled(true);
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请检查此
Ode*_*ner 13
我需要禁用在一个特定页面上滑动,并给它一个很好的橡皮筋动画,这里是如何:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
if (position == MANDATORY_PAGE_LOCATION && positionOffset > 0.5) {
mViewPager.setCurrentItem(MANDATORY_PAGE_LOCATION, true);
}
}
Run Code Online (Sandbox Code Playgroud)
L. *_*ter 12
我CustomViewPager用滑动控件写了一个:
public class ScrollableViewPager extends ViewPager {
private boolean canScroll = true;
public ScrollableViewPager(Context context) {
super(context);
}
public ScrollableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setCanScroll(boolean canScroll) {
this.canScroll = canScroll;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return canScroll && super.onTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return canScroll && super.onInterceptTouchEvent(ev);
}
}
Run Code Online (Sandbox Code Playgroud)
如果设置canScroll为true,ViewPager则可以用手指轻扫,false相反.
我在我的项目中使用它,直到现在它都运行良好.
Din*_*uka 11
我知道发布这篇文章的时间太晚了,但这是一个很小的黑客来实现你的结果;)
只需在viewpager 下面添加一个虚拟视图:
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<RelativeLayout
android:id="@+id/dummyView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
然后添加一个OnClickListener到你的RelativeLayout.
dummyView = (RelativeLayout) findViewById(R.id.dummyView);
dummyView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Just leave this empty
}
});
Run Code Online (Sandbox Code Playgroud)
通过布局,布局和行为获得一点创意,你将学会找到一种方法来完成你想象的任何事情:)
祝好运!
如果您使用的是 ViewPager2,则只需使用:
viewpager.setUserInputEnabled(false);
从文档:
启用或禁用用户启动的滚动。这包括触摸输入(滚动和滑动手势)和辅助功能输入。尚不支持禁用键盘输入。当用户启动的滚动被禁用时,通过 setCurrentItem 的编程滚动仍然有效。默认情况下,启用用户启动的滚动。
感谢:https : //stackoverflow.com/a/61685871/9026710
在 kotlin 中,我们可以通过创建一个继承 ViewPager 类的自定义小部件并添加一个标志值来控制滑动行为来解决这个问题。
NoSwipePager.kt
class NoSwipePager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {
var pagingEnabled: Boolean = false
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (this.pagingEnabled) {
super.onTouchEvent(event)
} else false
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return if (this.pagingEnabled) {
super.onInterceptTouchEvent(event)
} else false
}
}
Run Code Online (Sandbox Code Playgroud)
在 xml 中
class NoSwipePager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {
var pagingEnabled: Boolean = false
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (this.pagingEnabled) {
super.onTouchEvent(event)
} else false
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return if (this.pagingEnabled) {
super.onInterceptTouchEvent(event)
} else false
}
}
Run Code Online (Sandbox Code Playgroud)
以编程方式禁用滑动。如果kotlin-android-extensions在build.gradle 中应用了插件,则可以通过编写以下代码来禁用滑动。
view_pager.pagingEnabled = false
Run Code Online (Sandbox Code Playgroud)
否则,我们可以使用以下代码禁用滑动:
val viewPager : ViewPager = findViewById(R.id.view_pager)
viewPager.pagingEnabled = false
Run Code Online (Sandbox Code Playgroud)
我成功地使用了这堂课。需要重写executeKeyEvent,以避免在某些设备中使用箭头滑动或访问:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class ViewPagerNoSwipe extends ViewPager {
/**
* Is swipe enabled
*/
private boolean enabled;
public ViewPagerNoSwipe(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = false; // By default swiping is disabled
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return this.enabled ? super.onTouchEvent(event) : false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.enabled ? super.onInterceptTouchEvent(event) : false;
}
@Override
public boolean executeKeyEvent(KeyEvent event) {
return this.enabled ? super.executeKeyEvent(event) : false;
}
public void setSwipeEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Run Code Online (Sandbox Code Playgroud)
并在xml中这样调用它:
<package.path.ViewPagerNoSwipe
android:layout_width="match_parent"
android:layout_height="match_parent" />
Run Code Online (Sandbox Code Playgroud)
在 Kotlin 中,我的解决方案结合了上述答案。
class CustomViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
var swipeEnabled = false
override fun onTouchEvent(ev: MotionEvent?): Boolean {
return if (swipeEnabled) super.onTouchEvent(ev) else false
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return if (swipeEnabled) super.onInterceptTouchEvent(ev) else false
}
override fun executeKeyEvent(event: KeyEvent): Boolean {
return if (swipeEnabled) super.executeKeyEvent(event) else false
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
291283 次 |
| 最近记录: |