左右两侧两个RecyclerView互相联动,类似美团外卖点餐

概述

最近做项目需要用到两个RecyclerView互相联动的功能,类似美团外卖的点餐列表,不同的是项目用到的右侧是点击分类,所以我用了左侧RecyclerView和右侧RecyclerView包含两个TextView和GridView,然后找了很多资料,把遇到的问题记录下来和大家一起分享,有类似需要的朋友可以看一下。先上图:

                   

需求:

1.左侧联动右侧,点击左侧任意一项、背景变色、右侧对应位置滚动到顶部。

2.右侧联动左侧,右侧滚动,左侧需要同步右侧在顶部的位置。

3.就像图中所示,点击图1的9,会向下移动到中间位置,点击图2的12,会向上移动到中间位置。

左侧联动右侧

左侧联动右侧,在右侧侧RecyclerView的适配器中自定义一个得到position的方法,这个position从左侧的点击事件中传过来

 public void getSelectedPosition(int selectedPosition) {
        //调用移动位置的方法,直接移动到顶部第一个位置
        ((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(selectedPosition,0);
        //刷新
        notifyDataSetChanged();
    }

右侧联动左侧,并将左侧移动到中间位置

说一下大体思路吧,获得当前屏幕可见的第一项和最后一项,算出他们的中间值,通过getTop方法得到传入的position距离中间值的高度,然后调用scrollBy方法,注意在中间值的上方和下方要滑动的方向是不一样的。

扫描二维码关注公众号,回复: 1374017 查看本文章

需要注意这里有一个注意事项,就是getChildAt方法无法获取超出屏幕外的position的项,如果index大于屏幕中可见的Item数会返回null,左侧并没有滑动的监听,比如左侧滑动到最底部,右侧还在第一项,右侧往上滑动会直接程序崩溃,那么如果index大于屏幕中Item的数量,我们直接使用ScrollToPosition。

直接上代码吧:

public void moveToMiddle(int position) {
        //先从RecyclerView的LayoutManager中获取当前第一项和最后一项的Position
        int firstItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
        int lastItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition();
        //中间位置
        int middle = (firstItem + lastItem)/2;
        // 取绝对值,index下标是当前的位置和中间位置的差,下标为index的view的top就是需要滑动的距离
        int index = (position - middle) >= 0 ? position - middle : -(position - middle);
        //左侧列表一共有12个Item,如果>这个值会返回null,程序崩溃,如果>12直接滑到指定位置,或者getChildCount,都一样啦
        if (index >= recyclerView.getChildCount()) {
            recyclerView.scrollToPosition(position);
        } else {
            //如果当前位置在中间位置上面,往下移动,这里为了防止越界
            if(position < middle) {
               recyclerView.scrollBy(0, -recyclerView.getChildAt(index).getTop());
               // 在中间位置的下面,往上移动
            } else {
                recyclerView.scrollBy(0, recyclerView.getChildAt(index).getTop());
            }
        }
    }

总结

以上内容就是左右两侧联动的重点,其他基础的我也简单说一下:

首先适配器中要自己定义一个方法如getSelectedPosition来获得activity传回来的position,利用这个position,左侧在activity中获取自身的点击position和右侧滚动传来的position,然后可以在onBindViewHolder中设置背景色的变化,以及传入moveToMiddle中,右侧也一样,从activity中获取左侧的传来的position,进行滑动反馈。

RecyclerView没提供点击事件,需要自定义listener接口,ViewHolder中item的点击方法得到选中的position,调用自定义listener的onItemClick方法,传入position,listener的onItemClick方法在activity中被重写,调用适配器的getSelectedPosition向适配器中返回position。

右侧RecyclerView的GridView的使用和listView类似,注意一个问题就是GridView嵌套在其他布局内,只显示一行,需要重写GridView的onMeasure方法,自定义一个GridView。

至于数据问题,我上传的Demo是自己模拟的相同的数据,实际开发中一般需要从JSON中解析得来,那就是Json解析的问题了,附上Demo,大家一起学习。

源码地址:https://github.com/pengboboer/TwoRecyclerVIew

后续

如果想学习RecyclerView的使用,推荐大家看鸿洋大神的博客,写的很详细了。

转载请标明出处: 
http://blog.csdn.net/lmj623565791/article/details/45059587; 
本文出自:【张鸿洋的博客】


猜你喜欢

转载自blog.csdn.net/pengbo6665631/article/details/80400146