android viewpager 禁止滑动
android viewpager 禁止滑动
- 前言
- 一、viewpager 禁止滑动是什么,有现成方法吗?
- 二、使用setOnTouchListener
- 三、使用自定义viewpager
- 总结
前言
本文介绍了本人有一个相关的需求需要实现这一功能,在过程中发现自己之前没做过,然后记录下实现这一功能的过程及相关的小知识点。
一、viewpager 禁止滑动是什么,有现成方法吗?
viewpager 禁止滑动,就是在特殊的条件,比如说编辑的状态下,是不允许用户滑动的,但是看了下viewpager 的源码,也百度了一下,并没有现成的API可以直接禁用调viewpager 的滑动,毕竟人家这个组件就是要滑动的,没有这个API也很正常。所以我们需要自己实现。
二、使用setOnTouchListener
自己实现嘛,一般来说就是能偷懒则偷懒的,先定义了一个isInterceptTouch的布尔值变量,在编辑态下设置为true,拦截事件。示例代码如下:
mBinding.viewPager.setOnTouchListener(object : View.OnTouchListener{ override fun onTouch(v: View?, event: MotionEvent?): Boolean { Log.d(TAG, "onTouch: $isInterceptTouch ${event?.action}") return isInterceptTouch } })
调试过后发现还是能滑动,就是不流畅了,所以动了个小脑筋,在滑动的时候再把页面设置回来。划了一下没问题交给测试小伙伴了。代码现在是这个样子:
mBinding.viewPager.setOnTouchListener(object : View.OnTouchListener{ override fun onTouch(v: View?, event: MotionEvent?): Boolean { Log.d(TAG, "onTouch: $isInterceptTouch ${event?.action}") if (isInterceptTouch){ mBinding.viewPager.setCurrentItem(mPos,false) } return isInterceptTouch } })
三、使用自定义viewpager
然后把,就不出意外的出意外了,测试反馈说我一点一点的滑动,还是可以话,我试了下确实是这样,但是日志又打印的确实是true,表示确实把事件已经拦截了,我一下子脑子卡主了,想了好一会才反应过来。顺便带大家复习一下setOnTouchListener和onTouchEvent的区别。
setOnTouchListener和onTouchEvent是Android中用于处理触摸事件的两种方法,它们有以下区别:
- 职责不同:onTouchEvent是View类中的一个方法,用于处理由View对象接收到的触摸事件。而setOnTouchListener则是View类的一个方法,它允许你为View对象设置一个OnTouchListener对象,这个对象可以响应View的触摸事件。
- 触发时机不同:当用户的触摸事件发生时,会最先由最内层的View对象(如按钮等)响应,如果该View对象没有消费该事件(即onTouch方法返回false),则会将事件传递给其父View对象,依此类推。如果最内层的View对象消费了该事件(即onTouch方法返回true),则该事件不会被传递给其父View对象。
- 处理方式不同:onTouchEvent是直接在View类中定义的方法,它的触发需要依赖传递过来的触摸事件信息。而setOnTouchListener则是为View对象设置了一个监听器,当用户的触摸事件发生时,会先由最内层的View对象响应,如果没有被消费,则会传递给其父View对象的onTouch方法;如果已经被消费,则不会传递给其父View对象的onTouch方法。
从复习结果上看当走到setOnTouchListener的时候,触摸事件其实已经被viewPager消费了,所以才会拦截不住,动歪脑筋设置setCurrentItem是没有用的。
因此,为了实现这一个需求,我不仅要自定义viewpager,使用onTouchEvent方法对触摸事件进行拦截,还要使用onInterceptTouchEvent防止其他子层级拿到消费事件。
再复习下onInterceptTouchEvent方法:这个方法主要存在于ViewGroup类中,用于拦截触摸事件。当返回值为false时,可以将点击事件传递到下层去;当返回值为true时,在这一层拦截点击事件,不能传递到下层去。
所以这个时候我的自定义viewpager就变成了这个样子
import android.content.Context import android.util.AttributeSet import android.util.Log import android.view.MotionEvent import androidx.viewpager.widget.ViewPager class NoScrollViewPager : ViewPager { companion object { private const val TAG = "NoScrollViewPager" } private var isScrollAllowed = true constructor(context: Context?) : super(context!!) {} constructor(context: Context?, attrs: AttributeSet?) : super( context!!, attrs ) { } override fun onTouchEvent(event: MotionEvent): Boolean { Log.d(TAG, "onTouchEvent: $isScrollAllowed") return if (isScrollAllowed) { super.onTouchEvent(event) } else false } override fun onInterceptTouchEvent(event: MotionEvent): Boolean { Log.d(TAG, "onInterceptTouchEvent: $isScrollAllowed") return if (isScrollAllowed) { super.onInterceptTouchEvent(event) } else false } fun setScrollAllowed(scrollAllowed: Boolean) { isScrollAllowed = scrollAllowed } }
然后通过setScrollAllowed这个方法来控制是否禁止滑动ViewPager,这次没问题了。
总结
本文介绍了如何禁止Android中的ViewPager组件的滑动操作,由于ViewPager本就是为了滑动而设计的,因此并没有现成的API可以直接实现禁止滑动。通过自定义ViewPager并重写onTouchEvent和onInterceptTouchEvent方法,可以实现滑动拦截并禁止ViewPager的滑动操作。同时也介绍了setOnTouchListener和onTouchEvent的区别。