左右兩側兩個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方法,注意在中間值的上方和下方要滑動的方向是不一樣的。
需要注意這裡有一個注意事項,就是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的使用,推薦大家看鴻洋大神的部落格,寫的很詳細了。