实现列表悬浮标签「顶上去」的效果
列表顶部的标签悬浮大家应该都知道,但「顶上去」是个啥玩意?
看一下效果图就知道了,注意看顶部的悬浮标签切换时的效果:
这是我在之前一个自定义侧边索引栏的项目上修改的,对侧边索引栏的实现有兴趣的可以看一下之前的文章:自定义侧边快速索引栏
思路是这样子的:
- 布局里面增加一个和索引 item 长的一样的 view,默认显示列表第一项的索引字母。
- 监听列表的滑动,当列表可见的第二项是索引 item 时,计算并更新悬浮 view 的 y 坐标,让它处于索引 item 的上方。
- 监听列表的滑动,当列表可见第一项发生变化时,更新悬浮 view 显示的字母为当前可见第一项的索引字母。
感觉比想象中简单啊。可以看出逻辑都是在滑动事件里,我们用 RecyclerView 的 addOnScrollListener 方法监听列表的滑动事件,在监听器里面实现上面的逻辑。说的可能不是很好,看代码就知道多简单了。
监听器的代码如下:
class mScrollListener extends RecyclerView.OnScrollListener { private int mFlowHeight; private int mCurrentPosition = -1; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { mFlowHeight = vFlow.getMeasuredHeight(); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition(); View view = layoutManager.findViewByPosition(firstVisibleItemPosition + 1); if (view != null) { if (view.getTop() <= mFlowHeight && isItem(firstVisibleItemPosition + 1)) { vFlow.setY(view.getTop() - mFlowHeight); } else { vFlow.setY(0); } } if (mCurrentPosition != firstVisibleItemPosition) { mCurrentPosition = firstVisibleItemPosition; tvFlowIndex.setText(mList.get(mCurrentPosition).getFirstWord()); } } /** * @param position 对应项的下标 * @return 是否为标签项 */ private boolean isItem(int position) { return mAdapter.getItemViewType(position) == MainAdapter.VIEW_INDEX; } }
这样就已经实现「顶上去」的效果了,妥妥的。
最后说明一下,这个代码是使用 RecyclerView 实现的,要是用 ListView 的话是有问题的。ListView 的 item 使用 getTop() 方法,刚开始拿到的应该是 item 距离整个 ListView 最顶部的距离,要都是这样还好处理,但是复用 item 的时候这个值又发生了变化。
总之就是,在使用 ListView 的时候,我还没有好的实现方法。要是哪位知道怎么实现,希望可以留言分享一下,不胜感激!
源码地址
相关推荐
sfhong00 2020-06-05
sheikhdz 2020-05-18
chenjinlong 2020-05-05
安辉 2020-04-30
chenjinlong 2020-02-03
magic00 2019-12-24
fengyeezju 2019-12-12
magic00 2019-10-21
whale 2019-06-30
DaLei 2019-06-30
mbcsdn 2019-06-28
yinbaoshiguang 2019-06-27
whale 2019-06-26
Palingenesis 2019-06-26