实现列表悬浮标签“顶上去”的效果

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>