這個(gè)案例是通過子條目item為recycleview實(shí)現(xiàn)多條目聯(lián)動(dòng)两踏,使得recycleview支持橫向和縱向滑動(dòng)
話不多說 驳庭,先上Demo演示
Demo代碼:https://github.com/LgSecret/Linkagelayout
此Demo實(shí)現(xiàn)效果就是這種,基本無嵌套。擺脫使用HorizontalScrollView 嵌套橫向數(shù)據(jù)過多而導(dǎo)致的性能問題,自測(cè)demo數(shù)據(jù)橫向50條 縱向150條都很絲滑旷档,并且支持內(nèi)部recycleview自定義多布局實(shí)現(xiàn)復(fù)雜布局效果。
下面是Demo布局
上下滑動(dòng)整體是一個(gè)recycleview 可以直接實(shí)現(xiàn)歇拆,而左右滑動(dòng)聯(lián)動(dòng)頭部一起滑動(dòng)就是我們要解決的問題,為了避免嵌套解決性能問題范咨,此demo采用了子條目為recycleview 橫向滑動(dòng) 然后聯(lián)動(dòng)其它條目 還有頭部列表一起滑動(dòng)策略故觅。
接下來貼出關(guān)鍵實(shí)現(xiàn)聯(lián)動(dòng)代碼
//多條recycleview聯(lián)動(dòng)
public void initRecyclerView(RecyclerView recyclerView) {
recyclerView.setHasFixedSize(true);
//為每一個(gè)recycleview創(chuàng)建layoutManager
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//todo
// 通過移動(dòng)layoutManager來實(shí)現(xiàn)列表滑動(dòng) 此行是讓新加載的item條目保持跟已經(jīng)滑動(dòng)的recycleview位置保持一致
// 也就是上拉加載更多的時(shí)候 保證新加載出來的item 跟已經(jīng)滑動(dòng)的item位置保持一致
if (layoutManager != null && firstPos > 0 && firstOffset > 0) {
layoutManager.scrollToPositionWithOffset(firstPos + 1, firstOffset);
}
// 添加所有的 recyclerView
observerList.add(recyclerView);
//當(dāng)觸摸條目的時(shí)候 停止滑動(dòng)
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
for (RecyclerView rv : observerList) {
rv.stopScroll();
}
}
return false;
}
});
//添加當(dāng)前滑動(dòng)recycleview的滑動(dòng)監(jiān)聽
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//獲取顯示第一個(gè)item的位置
int firstPos1 = linearLayoutManager.findFirstVisibleItemPosition();
View firstVisibleItem = linearLayoutManager.getChildAt(0);
if (firstVisibleItem != null) {
//獲取第一個(gè)item的偏移量
int firstRight = linearLayoutManager.getDecoratedRight(firstVisibleItem);
//遍歷其它的所有的recycleview條目
for (RecyclerView rv : observerList) {
if (recyclerView != rv) {
LinearLayoutManager layoutManager = (LinearLayoutManager) rv.getLayoutManager();
if (layoutManager != null) {
firstPos = firstPos1;
firstOffset = firstRight;
//通過當(dāng)前顯示item的位置和偏移量的位置來置頂recycleview 也就是同步其它item的移動(dòng)距離
layoutManager.scrollToPositionWithOffset(firstPos + 1, firstRight);
}
}
}
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
}
上方的代碼還有注釋已經(jīng)很好的解釋了如何進(jìn)行多個(gè)recycleview進(jìn)行聯(lián)動(dòng)的方式,主要還是通過
layoutManager.scrollToPositionWithOffset(firstPos + 1, firstRight);
此方法來實(shí)現(xiàn)其它recycleview進(jìn)行聯(lián)動(dòng) 并且聯(lián)動(dòng)上方的recycleview