youlookwhat / ByRecyclerView

🔥 RecyclerView 下拉刷新、上拉松手/自动加载更多、item点击/长按、item局部刷新、头布局/尾布局/状态布局、万能分割线、Skeleton骨架图、极简adapter、嵌套滑动置顶
https://youlookwhat.github.io/ByRecyclerView
Apache License 2.0
807 stars 141 forks source link

列表在吸顶状态,然后detach再重新attach时,出现2个吸顶布局 #69

Closed gaojingwen945 closed 1 year ago

gaojingwen945 commented 1 year ago

您好,我的布局是这样的: ViewPager(offpageLimit默认为1) -> 5个Fragment -> ByRecyclerView,

目前发现一个问题是,当我的fragment里面的列表处于吸顶状态时,我在viewpager中切换到不相邻的fragment再切回来,会出现2个吸顶布局。

debug了一下,发现是在StickyLinearLayoutManager.onAttachedToWindow()中时,重新new了一个StickyHeaderHandler,用新的这个handler去做detachHeader()时,currentHeader为空直接返回了。

麻烦大佬看下?

youlookwhat commented 1 year ago

好的,我这边看看~

youlookwhat commented 1 year ago

我阳了... 要不你先自己看看怎么解决...

gaojingwen945 commented 1 year ago

😂 嗯嗯,我也阳了,一星期了... 也没啥精力,所以只是临时的解决了一下这个问题,等你好了再看下吧~

在StickyLinearLayoutManager里面:

@Override
    public void onAttachedToWindow(RecyclerView view) {
        viewHolderFactory = new ViewHolderFactory(view);

        // 先保存
        StickyHeaderHandler formerHandler = mHeaderHandler; 

        mHeaderHandler = new StickyHeaderHandler(view);
        mHeaderHandler.setElevateHeaders(headerElevation);
        if (mHeaderPositions.size() > 0) {
            mHeaderHandler.setHeaderPositions(mHeaderPositions); 

            // 再设置
            if (formerHandler != null) { 
                mHeaderHandler.setCurrentHeader(formerHandler.getCurrentHeader());
            }

            resetHeaderHandler();
        }
        super.onAttachedToWindow(view);
    }
youlookwhat commented 1 year ago

我在demo里的StickyItemActivity类里模仿了你那种情况,但是没复现,你咋出现的呢,要不用demo复现一下我测一下。

StickyItemActivity里改了这里:

   private void initFragmentList() {
        mTitleList.clear();
        mTitleList.add("线性列表");
        mTitleList.add("宫格列表");
        mTitleList.add("宫格列表");
        mTitleList.add("宫格列表");
        mTitleList.add("宫格列表");
        mFragments.add(StickyLinearFragment.newInstance(""));
        mFragments.add(StickyGridFragment.newInstance(""));
        mFragments.add(StickyGridFragment.newInstance(""));
        mFragments.add(StickyGridFragment.newInstance(""));
        mFragments.add(StickyGridFragment.newInstance(""));
    }
gaojingwen945 commented 1 year ago

我试了下,按你上面的修改确实不会出现这个问题,区别在于: 你这里每次回到第一个fragment时,会在StickyLinearFragment.onActivityCreated()里面重新new一个layoutManager,而我那边没有。 这就导致我那边每次回到这个fragment时,走到layoutManager.onAttachedToWindow()时,mHeaderPositions.size() = 1,而你这里因为是一个新的layoutManager实例,mHeaderPositions.size() = 0。

youlookwhat commented 1 year ago

因为每次回到这个fragment时,相当于重建了fragment,所以会重新new一个layoutManager。

你重新new一个layoutManager会有什么影响吗

gaojingwen945 commented 1 year ago

嗯。。我这边不会每次都new layoutManager,只在fragment创建时才会走我的初始化逻辑。实现不一样。

youlookwhat commented 1 year ago

但是你offpageLimit默认为1,切到第三个fragment去再切回来不就相当于销毁了重建嘛。你是不是fragment懒加载那一块有点问题啊

gaojingwen945 commented 1 year ago

没有呀,再切回来fragment还是那个fragment呀,fragment对象又没有重新创建。

youlookwhat commented 1 year ago

正常的逻辑我理解是: offpageLimit默认为1, 如果是切到第三个,这时候第一个fragment走了ondestroyView方法,相当于这个fragment里东西被清了,这时候再回到这个fragment,可以重新初始化fragment,可以new layoutManager。 如果你是切到第二个,这时候第一个fragment是还在内存中的,相当于没有任何变化,所以也不会存在重新 走onAttachedToWindow的情况

youlookwhat commented 1 year ago

有问题再提了~