Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

向下滑动时,在两个组别切换的时候,假头会闪一下,Demo中也会出现这个现象 #41

Open
WanDa1993 opened this issue Jan 21, 2021 · 7 comments
Labels

Comments

@WanDa1993
Copy link

研究源码的过程中,测试发现的。不算大问题,算是一个小瑕疵。顺便感谢下作者~

@WanDa1993
Copy link
Author

组别:A B C D E 。。。。
向上滑动 从 D -> C 临界切换的时候会闪一下。

@WanDa1993
Copy link
Author

                if (mFirstVisiblePosition != firstPosition && firstPosition >= 0) {
                    mFirstVisiblePosition = firstPosition;
                    mTvHeader.setY(0);

                    String currentGroupName = items.get(mFirstVisiblePosition).isHeader
                            ? items.get(mFirstVisiblePosition).header
                            : items.get(mFirstVisiblePosition).info.getGroup();

                    if (TextUtils.isEmpty(mLastGroupName) || !mLastGroupName.equals(currentGroupName)) {
                        mLastGroupName = currentGroupName;
                        groupNameChanged = true;
                        mTvHeader.setText(mLastGroupName);
                    }
                }

应该在临界的时候 先触发这段代码,先设置Header Y 坐标 = 0 ,然后赋值

@WanDa1993
Copy link
Author

然后才执行这段逻辑

            if (firstCompletePosition > 0 && (firstCompletePosition) < items.size()
                    && items.get(firstCompletePosition).isHeader) {

                View view = mSecondaryLayoutManager.findViewByPosition(firstCompletePosition);
                if (view != null && view.getTop() <= mTitleHeight) {
                    mTvHeader.setY(view.getTop() - mTitleHeight);
                }
            }

上移Header

才会造成闪一下

@WanDa1993
Copy link
Author

问题我找到了解决思路,在重新描述下问题,以及解决思路,供作者参考:

问题产生场景:

已知组别:A、B、C、D、E

已知占位Header:tvHeader

复现步骤:

(1)先滑动到tvHeader与组别B的头部重合,此时tvHeader显示B

(2)慢速向上滑动,只到A组的底部刚刚出现的临界

(3)tvHeader 会迅速更新成A的名称,然后进行tvHeader.y = -titleHeight的操作

(4)此时会发现tvHeader名称变化成A,然后闪烁一下,之后又显示B组别的Title,这个过程比较快。很容易复现出来

@WanDa1993
Copy link
Author

解决方案:

研究下源码,造成这个现象是由于如下代码造成的

LinkageRecyclerView#200

                boolean groupNameChanged = false;

                if (mFirstVisiblePosition != firstPosition && firstPosition >= 0) {
                    mFirstVisiblePosition = firstPosition;
                    mTvHeader.setY(0);

                    String currentGroupName = items.get(mFirstVisiblePosition).isHeader
                            ? items.get(mFirstVisiblePosition).header
                            : items.get(mFirstVisiblePosition).info.getGroup();

                    if (TextUtils.isEmpty(mLastGroupName) || !mLastGroupName.equals(currentGroupName)) {
                        mLastGroupName = currentGroupName;
                        groupNameChanged = true;
                        mTvHeader.setText(mLastGroupName);
                    }
                }

上面这段的代码,我理解的含义是只要发生第一个可见的Item变化,此时就会将tvHeader的y坐标设置成0,然后刷新tvHeader的text

造成原因:

其实在第一个可见Item切换时,会存在两种情况

(1)向下滑动 && 第一个可见Item变化

(2)向上滑动 && 第一个可见Item变化

向下滑动:

向下滑动时&&第一个Item变化,因为此时tvHeader和SecondaryRv的标题Item并不重合,所以不需要重置tvHeader的Y轴坐标,闪烁的本质也是因为重置Y坐标,同时更新Text

向上滑动:

向上滑动时&&第一个Item变化,需要重置tvHeader的Y轴坐标,因为此时tvHeader和SecondaryRv的标题Item重合

@WanDa1993
Copy link
Author

解决方案:


                if (firstCompletePosition > 0 && (firstCompletePosition) < items.size()
                        && items.get(firstCompletePosition).isHeader) {

                    View view = mSecondaryLayoutManager.findViewByPosition(firstCompletePosition);
                    if (view != null && view.getTop() <= mTitleHeight) {
                        mTvHeader.setY(view.getTop() - mTitleHeight);
                    }
                } else {
                    //改动二: 如果不进行粘性头的操作时,此时重置Y轴坐标
                    mTvHeader.setY(0);
                }

                // Here is the logic of group title changes and linkage:

                boolean groupNameChanged = false;

                if (mFirstVisiblePosition != firstPosition && firstPosition >= 0) {

                    //改动一: 只判断上滑时,才会重置mTvHeader的Y轴坐标
                    if (mFirstVisiblePosition < firstPosition) {
                        mTvHeader.setY(0);
                    }
                    
                    mFirstVisiblePosition = firstPosition;

   

                    String currentGroupName = items.get(mFirstVisiblePosition).isHeader
                            ? items.get(mFirstVisiblePosition).header
                            : items.get(mFirstVisiblePosition).info.getGroup();

                    if (TextUtils.isEmpty(mLastGroupName) || !mLastGroupName.equals(currentGroupName)) {
                        mLastGroupName = currentGroupName;
                        groupNameChanged = true;
                        mTvHeader.setText(mLastGroupName);
                    }
                }

@KunMinX
Copy link
Owner

KunMinX commented Jan 21, 2021

@Vander-liu

非常感谢你的细心测试和反馈,已提交修改 😉

@KunMinX KunMinX added the 精华 label Jun 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants