Recyclerview 实现双联表联动

今天实现的效果如下:

工程可以参考:实现一个可定制的 Tab 或者 Label flow

一、左边联动右边

首先,先看 recycleview 的联动;我们知道 ,要让Recyclerview 滚动,我们可以使用

 mRecyclerView.smoothScrollToPosition(position);

使布局平滑移动,但是需要注意的是;当我们点击左边的目标 item 2时;需要分几种情况讨论,这里我们统一左边的item为目标 item:
Recyclerview 实现双联表联动_第1张图片

  1. 当目标 item 在 可视区域的上面,调用该函数,可以滚动到具体区域
  2. 当目标item,在可视区域的中间,假如在上图中,点击 “开发社区”,它是不起作用的,因为 smoothScrollToPosition 方法只是把 item 从不可见移到可视区域,所以没有效果。
  3. 当目标 item ,在可视区域的下面,即不可见;使用该方法,会把它移动到可视区域;

综上,我们的方法如下:

 @Override
 public void onItemClick(View view, NaviBean data, int position) {
       super.onItemClick(view, data, position);
       int firstPosition = mManager.findFirstVisibleItemPosition();
       int lastPosition = mManager.findLastVisibleItemPosition();
       mCurPosition = position;

       /**
        * 目标在 可见视图的上面,第一种情况
        */
       if (position <= firstPosition) {
           mRecyclerView.smoothScrollToPosition(position);
           //防止不刷新视图
           mRecyclerView.requestLayout();
       } else if (position <= lastPosition) {
           //往下点,且 position 在中间,但是 lastposition 的数据也能看到.所以把它置顶
           /**
            * 目标在 first 和 last 的中间,第二种情况
            */
           int top = mRecyclerView.getChildAt(position - firstPosition).getTop();
           if (top > 0) {
               mRecyclerView.smoothScrollBy(0, top);
           }

       } else {
           /**
            * 目标在可视视图的下面,第三种情况
            */
           //该函数让它滚动到可视界面
           mRecyclerView.scrollToPosition(position);
           //此时recycler 的item还未滚动到顶端,需要重新再让它滚动改一下
           isNeedScroll = true;
       }
   }

第二种情况的时候,需要拿到目标 item 的 top 高度,然后直接移动即可。但这里需要 目标 item 的 position - firstPosition ;比如当前可见区域的第一个item 为4,你想打击6,实际是 6-4=2;mRecyclerview.getchilat(2) 的高度。

第三种情况的时候,因为只是把不可见移动到可见,所以此时还需要重复2 的操作;但是,我们可以监听 mRecyclerviw 的 scrollListner:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (isNeedScroll){
                isNeedScroll = false;
                int index = mCurPosition - mManager.findFirstVisibleItemPosition();
                if (index >= 0 && mRecyclerView.getChildCount() > index){
                    int top = mRecyclerView.getChildAt(index).getTop();
                    mRecyclerView.smoothScrollBy(0,top);
                }
            }
        }
    });

二、右边联动左边

当我们移动了recyclerview 之后,则需要把 某个 item 置顶,并把左边的也移动到对应的 item;
也从 scrolllistener 下手,当滚动结束之后,再执行一遍刚才的操作即可!! 但如果不限制,那就会变得右边影响了左边,左边影响了右边,反复循环。
所以这里增加一个标志位,可以使用 mTabFlowLayout.isItemClick() 判断是否是从左边的 item 点击的。如果是,则不用管,如果不是,即recyclerview 自己滑动的,则重新执行一遍过程即可。如下

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (newState == RecyclerView.SCROLL_STATE_IDLE){

            int firstPosition = mManager.findFirstVisibleItemPosition();
            if (!mTabFlowLayout.isItemClick()) {
                mTabFlowLayout.setItemSelected(firstPosition);
                mTabFlowLayout.setItemClickStatus(true);
            }else{
                /**
                 * 如果上次为点击事件,则先还原,下次滑动时,监听即可
                 */
                mTabFlowLayout.setItemClickStatus(false);
            }

        }
    }
});

具体,可以参考上面的工程链接

你可能感兴趣的:(Android-实例,recyclerview)