android 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中用于处理触摸事件的两种方法,它们有以下区别:

  1. 职责不同:onTouchEvent是View类中的一个方法,用于处理由View对象接收到的触摸事件。而setOnTouchListener则是View类的一个方法,它允许你为View对象设置一个OnTouchListener对象,这个对象可以响应View的触摸事件。
  2. 触发时机不同:当用户的触摸事件发生时,会最先由最内层的View对象(如按钮等)响应,如果该View对象没有消费该事件(即onTouch方法返回false),则会将事件传递给其父View对象,依此类推。如果最内层的View对象消费了该事件(即onTouch方法返回true),则该事件不会被传递给其父View对象。
  3. 处理方式不同: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的区别。

猜你喜欢

转载自blog.csdn.net/shop_and_sleep/article/details/134682506