实现列表悬浮标签“顶上去”的效果
auoo7681
8年前
<p>列表顶部的标签悬浮大家应该都知道,但“顶上去”是个啥玩意?</p> <p>看一下效果图就知道了,注意看顶部的悬浮标签切换时的效果:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/40910071ad9b5f269135d3c0023b64c4.gif"></p> <p>这是我在之前一个自定义侧边索引栏的项目上修改的,对侧边索引栏的实现有兴趣的可以看一下之前的文章:自定义侧边快速索引栏</p> <p>思路是这样子的:</p> <ul> <li>布局里面增加一个和索引item长的一样的view,默认显示列表第一项的索引字母。</li> <li>监听列表的滑动,当列表可见的第二项是索引item时,计算并更新悬浮view的Y坐标,让它处于索引item的上方。</li> <li>监听列表的滑动,当列表可见第一项发生变化时,更新悬浮view显示的字母为当前可见第一项的索引字母。</li> </ul> <p>感觉比想象中简单啊。可以看出逻辑都是在滑动事件里,我们用RecyclerView的addOnScrollListener方法监听列表的滑动事件,在监听器里面实现上面的逻辑。说的可能不是很好,看代码就知道多简单了。</p> <p>监听器的代码如下:</p> <pre> <code class="language-java">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; } }</code></pre> <p>这样就已经实现“顶上去的效果了”,妥妥的。</p> <p>最后说明一下,这个代码是使用RecyclerView实现的,要是用ListView的话是有问题的。ListView的item使用getTop()方法,刚开始拿到的应该是item距离整个ListView最顶部的距离,要都是这样还好处理,但是复用item的时候这个值又发生了变化。</p> <p> </p> <p> </p> <p> </p> <p>来自:http://www.jianshu.com/p/67634a170333</p> <p> </p>