美文网首页
使用viewpager2+TabLayout + recycle

使用viewpager2+TabLayout + recycle

作者: 梧叶已秋声 | 来源:发表于2022-11-28 10:36 被阅读0次

代码地址:
https://github.com/VIVILL/SimpleDemo/tree/main/ViewPager2/slideconflict

当使用viewpager2+TabLayout + recyclerview 的时候,recyclerview上拉时,由于viewpager2灵敏度较高,容易造成 外层 viewpager2 横向滑动,导致 TabLayout 切换。
结构如下所示:

image.png
此时需要禁止viewpager2 滑动。
解决思路:
自定义recyclerview,重写dispatchTouchEvent,将MotionEvent数据回传给使用recyclerview的fragment,通过activityViewModels在fragment之间共享viewmodel,在HomeFragment中,当横向移动大小小于竖向移动大小时,禁止viewpager2滑动,从而降低ViewPager2灵敏度。
class TouchEventRecyclerView: RecyclerView {
    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
    }

    private lateinit var onTouchEventListener: (ev: MotionEvent)  -> Unit
    fun setTouchEventListener(onTouchEventListener : (ev: MotionEvent)  -> Unit){
        this.onTouchEventListener = onTouchEventListener
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        Log.d(TAG,"inner dispatchTouchEvent")
        // 将 MotionEvent 回传
        onTouchEventListener(ev)
        return super.dispatchTouchEvent(ev)
    }

}

定义viewmodel。

class TouchViewModel: ViewModel() {

    private val _recyclerviewTouchAction = MutableSharedFlow<TouchAction>()
    val recyclerviewTouchAction: SharedFlow<TouchAction> = _recyclerviewTouchAction

    fun touchRecyclerview(event: MotionEvent) {
        viewModelScope.launch {
            _recyclerviewTouchAction.emit(TouchAction.Touch(event))
        }
    }

}

sealed class TouchAction {
    data class Touch(val event: MotionEvent): TouchAction()
}

将事件回传。

// FirstFragment.kt
        binding.recyclerview.setTouchEventListener{
            Log.d(TAG,"inner setTouchEventListener")
            viewModel.touchRecyclerview(it)
        }

在TabLayout所在的fragment,订阅事件,增加合适的判断条件,这里是当横向移动大小小于竖向移动大小时,禁止viewpager2滑动。

// HomeFragment
    private fun subscribeUI() {
        viewLifecycleOwner.lifecycleScope.launch(exceptionHandler){
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.recyclerviewTouchAction.collect {
                    when (it) {
                        is TouchAction.Touch -> {
                            Log.d(TAG, "inner Touch")
                            when (it.event.action) {
                                MotionEvent.ACTION_DOWN -> {
                                    Log.d(TAG, "inner MotionEvent.ACTION_DOWN")
                                    startX = it.event.x.toInt()
                                    startY = it.event.y.toInt()
                                    Log.d(TAG,"ACTION_DOWN startX = $startX startY = $startY ")
                                }
                                MotionEvent.ACTION_MOVE -> {
                                    val endX = it.event.x.toInt()
                                    val endY = it.event.y.toInt()
                                    val disX = abs(endX - startX)
                                    val disY = abs(endY - startY)
                                    if (disX < disY) {
                                        binding.viewPager2.isUserInputEnabled = false
                                        Log.d(TAG, "inner ACTION_MOVE binding.viewPager2.isUserInputEnabled = false")

                                    }
                                }
                                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL-> {
                                    Log.d(TAG, "inner MotionEvent.ACTION_UP or ACTION_CANCEL binding.viewPager2.isUserInputEnabled = true")
                                    startX = 0
                                    startY = 0
                                    binding.viewPager2.isUserInputEnabled = true
                                }

                                else -> {}
                            }
                        }

                    }
                }
            }
        }
    }

参考链接:
YuLook-解决ViewPager2滑动灵敏问题
https://www.jianshu.com/p/42d05885461a

相关文章

网友评论

      本文标题:使用viewpager2+TabLayout + recycle

      本文链接:https://www.haomeiwen.com/subject/pvylfdtx.html