Xzmpyy 2019-02-27 20:16 采纳率: 50%
浏览 969
已采纳

如何解决ViewPager+Fragment+GridView实现无限滑动时页面切换的卡顿问题?

最近想自己写一个日历组件,思路是使用ViewPager+Fragment+GridView,如图

(https://img-ask.csdn.net/upload/201902/27/1551263494_687583.png)

最外层是一个DialogFragment

如果正常滑动,没有任何问题,但在快速滑动的时候,在滑到Fragment1和4时进行setCurrentItem时,会发生卡顿现象,即没有即时跳转导致已达到边界无法继续滑动的情况

慢滑

(https://img-ask.csdn.net/upload/201902/27/1551269528_523451.gif)

快滑

(https://img-ask.csdn.net/upload/201902/27/1551269556_845553.gif)

我自己尝试过的解决办法:
1. 一开始我以为是Fragment中布局过于复杂,导致在刷新数据时卡顿,但即时我去掉Fragment中的所有布局,仍会发生卡顿现象
2.后来我将问题定位在ViewPager的事件分发上,将ViewPager的自定义,将onInterceptTouchEvent方法复写直接返回true,现象消失,滑动无问题,但由于GridView中需要响应点击事件,所以我又做了事件拦截的判断,但无论怎么判断,只要不直接返回true,该现象就会发生

下面贴上我的部分代码:
1. 我在DialogFragment中为ViewPager绑定监听事件,在onPageScrollStateChanged中判断页面是否跳转,在页面滑到最左最右时进行跳转

//滑动状态监听

                override fun onPageScrollStateChanged(p0: Int) {
                    //1时表示正在滑动、2时表示滑动完毕、0时什么都没做,滑动时变化顺序为1>2>0
                    //在0时设置页面位置互换
                    if (p0 == 0){
                        position = calViewPager.currentItem
                        when (position) {
                            0 -> {
                                //到达最左侧Fragment时,刷新倒数第二个Fragment的数据与其保持一致,然后跳转,刷新部分代码省略
                                calViewPager.setCurrentItem(2, false)
                                //跳转完成后刷新其余页面,代码省略
                            }
                            3 -> {
                               //到达最右侧Fragment时,刷新第二个Fragment的数据与其保持一致,然后跳转,刷新部分代码省略
                                calViewPager.setCurrentItem(1, false)
                              //跳转完成后刷新其余页面,代码省略
                            }
                            2 -> {
                                //数据刷新,代码省略
                            }
                            1 -> {
                               //数据刷新,代码省略
                            }
                        }
                    }
                }

2.自定义了ViewPager,进行了事件拦截处理

private var xPosition:Float? = null
//    滑动点击判断、拦截
    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        val res = super.onInterceptTouchEvent(ev)
        xPosition = if (ev!!.action == MotionEvent.ACTION_DOWN){
            ev.x
        }else{
            if (Math.abs(ev.x - xPosition!!) > 0){
                return true
            }else{
                ev.x
            }
        }
            return res
    }

3.ViewPager的Adapter

class MyCalendarViewPagerAdapter(fm: FragmentManager, private var fragmentsList:MutableList<Fragment>): FragmentPagerAdapter(fm){
    //Fragment个数
    override fun getCount(): Int {
        return fragmentsList.size
    }


    override fun getItem(p0: Int): Fragment {
        return fragmentsList[p0]
    }

    //不销毁Item
    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {

    }

    override fun getItemPosition(`object`: Any): Int {
        return PagerAdapter.POSITION_NONE
    }

}

4.在Fragment中是使用回调进行的数据更新,代码就不上了

这个问题已经困扰我两周了 求大佬指点

  • 写回答

2条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      悬赏问题

      • ¥15 ME21N 创建采购成功并且生成采购订单号,但显示“快件文档更新已取消”,SM13看错误提示为如下截图:
      • ¥30 android 集成fmod实现变声功能中遇到的问题
      • ¥60 matlab传染病模型分段
      • ¥15 关于#matlab#的问题,如何解决?
      • ¥15 51单片机汇编语言Keil5基础问题!
      • ¥15 CygwinPortable 中 NumPy 无法安装
      • ¥15 vivado如何支持多维打包数组模式
      • ¥15 请问第13题到底应该怎么做
      • ¥15 倒计时汇编语言RTC实时时钟
      • ¥15 CCS安装出现Failed to create the part's controls