解决SwipeRefreshLayout和RecyclerView时滑动冲突

706 阅读1分钟

问题复现

SwipeRefreshLayout嵌套RecyclerView,当内容超过屏幕下拉,不知道你是要下拉刷新还是下滑,一直认为你是下拉刷新。

recycler_refresh

【问题伪代码】

 class LogoActivity : AppCompatActivity() {
 ​
     private lateinit var binding: ActivityLogoBinding
 ​
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         binding = ActivityLogoBinding.inflate(layoutInflater)
         setContentView(binding.root)
 ​
         // 初始化xml控件
         mRecyclerView = binding.mRecyclerView 
         mRefreshLayout = binding.refreshLayout
         
         onPullRefresh()
         onLoadMore()
     }
     
      /**
      * 下拉刷新
      */
     private fun onPullRefresh() {
         mRefreshLayout.setColorSchemeColors(Color.parseColor("#03A9F4"))
         mRefreshLayout.setOnRefreshListener {
             thread {
                 Thread.sleep(700) // 这个延迟0.7秒只是为了实现视觉效果,与逻辑无关
                 runOnUiThread {
                     loadNewData()
                     mRefreshLayout.isRefreshing = false // 让圆形进度条停下来
                 }
             }
         }
     }
     
         private fun onLoadMore() {
         // 设置加载更多监听
         mRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
             override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                 super.onScrollStateChanged(recyclerView, newState)
                 val manager = recyclerView.layoutManager as LinearLayoutManager
                 if (manager != null) {
                     // 当不滑动时
                     when (newState) {
                         RecyclerView.SCROLL_STATE_IDLE -> {
                             loadNewData()
                         }
                         RecyclerView.SCROLL_STATE_DRAGGING -> {}
                         RecyclerView.SCROLL_STATE_SETTLING -> {}
                         else -> {}
                     }
                 }
             }
 ​
             override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                 super.onScrolled(recyclerView, dx, dy)
                 // TODO: 在此处解决滑动冲突
             }
         })
     }
 }

解决方式

在1上述TODO处添加代码

mRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
     override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
         super.onScrolled(recyclerView, dx, dy)
         val topRowVerticalPosition =
             if (recyclerView == null || recyclerView.childCount === 0)
                 0 else recyclerView.getChildAt(0).top
         // 大于0表示正在向上滑动,小于等于0表示停止或向下滑动
         mRefreshLayout.isEnabled = topRowVerticalPosition >= 0
     }
 })

添加好后,再测试一下就可以正常滑动了!