栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

解决折叠状态栏+viewPager2嵌套带有下拉刷新的RecyclerView滑动冲突

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

解决折叠状态栏+viewPager2嵌套带有下拉刷新的RecyclerView滑动冲突

CoordinatorLayout+AppBarLayout+viewPager2+fragment+下拉刷新的RecyclerView

下滑

上滑

当手指下滑的时候,因为AppBarLayout还没有折叠,滑动事件会被PtrframeLayout消费,但上滑是如果AppBarLayout还没有折叠,滑动事件也会被PtrframeLayout消费但和AppBarLayout.Behavior的滑动产生冲突,会发生滑动抖动,网上说重写AppBarLayout.Behavior可以解决,或者重写PtrframeLayout,对上下滑动事件进行拦截,也可以。
这个涉及安卓事件分发机制,不会的朋友可以搜一下。
当下滑时让PtrframeLayout自行消费,上滑时进行拦截。
以上是我个人理解,有错误希望大佬指出。
上代码。
fragment_home.xml



    
    

        

            
                

                    

                    
                
            



            

        


            

    


重写PtrframeLayout

class PullRefreshLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : PtrframeLayout(context, attrs, defStyleAttr), PtrUIHandler {

    private val viewBinding = ViewRecyclerHeaderBinding.inflate(LayoutInflater.from(context), this, false)
    private var onPullRefreshListener: OnPullRefreshListener? = null

    companion object {
        private const val TAG = "PullRefreshLayout"
    }

    init {
        disableWhenHorizontalMove(true)
        isKeepHeaderWhenRefresh = true
        setRatioOfHeaderHeightToRefresh(1F)
        headerView = viewBinding.root
        addPtrUIHandler(this)
        setPtrHandler(
            object : PtrDefaultHandler() {
                override fun onRefreshBegin(layout: PtrframeLayout) {
                    onPullRefreshListener?.onRefreshBegin()
                }
            })
    }

    override fun onUIReset(layout: PtrframeLayout) {

    }

    override fun onUIRefreshPrepare(layout: PtrframeLayout) {
        Log.d(TAG, "onUIRefreshPrepare")
        viewBinding.tvRefreshState.setText(R.string.refresh_pull_down_to_refresh)
    }

    override fun onUIRefreshBegin(layout: PtrframeLayout) {
        Log.d(TAG, "onUIRefreshBegin")
        viewBinding.tvRefreshState.setText(R.string.refresh_refreshing)
    }

    override fun onUIRefreshComplete(layout: PtrframeLayout) {
        Log.d(TAG, "onUIRefreshComplete")
        viewBinding.tvRefreshState.setText(R.string.refresh_refresh_complete)
    }

    override fun onUIPositionChange(layout: PtrframeLayout, isUnderTouch: Boolean, status: Byte, ptrIndicator: PtrIndicator) {
        val offsetToRefresh: Int = layout.offsetToRefresh
        val currentPos = ptrIndicator.currentPosY
        val lastPos = ptrIndicator.lastPosY

        if (currentPos < offsetToRefresh && lastPos >= offsetToRefresh) {
            if (isUnderTouch && status == PTR_STATUS_PREPARE) {
                viewBinding.tvRefreshState.setText(R.string.refresh_pull_down_to_refresh)
            }
        } else if (currentPos > offsetToRefresh && lastPos <= offsetToRefresh) {
            if (isUnderTouch && status == PTR_STATUS_PREPARE) {
                viewBinding.tvRefreshState.setText(R.string.refresh_release_to_refresh)
                performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
            }
        }
    }

    fun setOnPullRefreshListener(listener: OnPullRefreshListener) {
        this.onPullRefreshListener = listener
    }

    interface onPullRefreshListener {
        fun onRefreshBegin()
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {

        val x: Float = ev.getX()
        val y: Float = ev.getY()
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                //将按下时的坐标存储
                downX = x
                downY = y
            }
            MotionEvent.ACTION_MOVE -> {
                //获取到距离差
                val dx: Float = x - downX
                val dy: Float = y - downY
                //通过距离差判断方向
                val orientation: Int = getOrientation(dx, dy)
                when (orientation) {
                    UP ->{
                        return super.dispatchTouchEventSupper(ev)
                    }
                }
            }

        }
        return super.dispatchTouchEvent(ev)
    }

    override fun dispatchTouchEventSupper(ev: MotionEvent): Boolean {

        val x: Float = ev.getX()
        val y: Float = ev.getY()
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                //将按下时的坐标存储
                downX = x
                downY = y
            }
            MotionEvent.ACTION_MOVE -> {
                //获取到距离差
                val dx: Float = x - downX
                val dy: Float = y - downY
                //通过距离差判断方向
                val orientation: Int = getOrientation(dx, dy)
                when (orientation) {
                    UP ->{
                        return super.dispatchTouchEventSupper(ev)
                    }
                }
            }

        }
        return super.dispatchTouchEventSupper(ev)
    }

    private var downX: Float = 0f//按下时 的X坐标
    private var downY: Float = 0f//按下时 的Y坐标
    private val LEFT: Int = 0
    private val RIGHT: Int = 1
    private val UP: Int = 2
    private val DOWN: Int = 3
    private fun getOrientation(dx: Float, dy: Float): Int {
        return if (Math.abs(dx) > Math.abs(dy)) {
            //X轴移动
            if (dx > 0) RIGHT else LEFT //右,左
        } else {
            //Y轴移动
            if (dy > 0) DOWN else UP //下//上
        }
    }

view_recycler_header.xml




    

        

    


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/271658.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号