RecyclerView高階之層疊列表(下)

2021-09-11 10:16:19 字數 2614 閱讀 8671

昨天寫了recyclerview高階之層疊列表(上),不過只實現了基本的效果。今天看到很多人點贊,於是我趁熱打鐵,把這個控制項寫完成吧。沒看過前篇的同學,先移步熟悉下吧。下篇的主要內容就是實現層疊列表邊緣的層疊動畫和recyclerview的**復用,也是這個控制項實現的難點所在。

關於這個,先上圖吧:

對比系統通知欄的滑動效果,細心的同學就發現了,無論是頂部還是底部,itemview靠近邊緣的時候並沒有變慢,從而產生乙個多層層疊的效果,所以我們先來實現這個效果。 先定義兩個動畫引數:

private @floatrange(from = 0.01, to = 1.0)

float edgepercent = 0.5f;//觸發邊緣動畫距離百分比

private @intrange(from = 1)

int slowtimes = 5;//到達此距離後放慢倍數

複製**

然後在滾動時重新布局列表各個itemview位置的方法中處理動畫,關鍵點是在itemview到達邊界臨界點時,將原本的偏移值除以乙個倍數,使其移動速度變慢:

private

void

addandlayoutviewvertical

(recyclerview.recycler recycler, recyclerview.state state, int offset)

} else }}

複製**

上面是底部邊界動畫的處理,頂部邊界動畫的處理也是一樣的。現在我們已經可以看到有層疊的效果了:

橫向的看起來效果也不錯:

這個功能如果沒有實現的話,就對不起recyclerview的名號了。下面都只貼了核心**:

@override

public

intscrollverticallyby

(int dy, recyclerview.recycler recycler, recyclerview.state state)

複製**

上面已經吧所有的itemview移除了,現在遍歷所有的itemview,判斷是否在螢幕中顯示,是的話就重新新增進去,不是的話就跳過。因為有邊緣層疊動畫,我們放慢了速度,但是比較的仍是原來滾動的距離,overflyingdist= slowtimes * height;

private void addandlayoutviewvertical(recyclerview.recycler recycler, recyclerview.state state, int offset) 

int displayheight = getverticalspace();

for (int i = itemcount - 1; i >= 0; i--)

if (topoffset < -overflyingdist && i != 0 && topoverflying

|| topoffset < -overflyingdist && !topoverflying)

if (needadd)

log.d(tag, "childcount = " + getchildcount() + " itemcount= " + itemcount);

}複製**

列印日誌看下結果,即使把列表總數加到1000項,recyclerview中的itemview數量也始終維持在實際顯示數量附近,順便也解決了因為itemview沒有**,兩邊陰影層疊在一起形成黑邊的問題:

到這已經基本實現了我們所期望的功能。但是和系統自帶的三個layoutmanager相比,還欠缺很多基本的對外操作方法,所以我們來依照linearlayoutmanager實現幾個同名方法:

findviewbyposition(int position)

@override

public view findviewbyposition

(int position)

final

int firstchild = getposition(getchildat(0));

final

int viewposition = position - firstchild;

if (viewposition >= 0 && viewposition < childcount)

}return

super.findviewbyposition(position);

}複製**

findviewbyposition(int position)

requestlayout()方法會呼叫onlayoutchildren(),offsetuseful用來標識onlayoutchildren()時是否將引數重置

@override

public

void

scrolltoposition

(int position)

else

}requestlayout();

}複製**

github位址

recyclerview之禁止滑動

找了好長時間查詢到乙個真正可以禁止滑動的。這個主要是記錄一下,怕下次忘了 在new linearlayoutmanager時 用下面這種方法就行了。主要的點 是第二個形參,他是判斷橫向和縱向的,下面這個就是縱向的 還有就是 方法名也是縱向的。在想橫向禁止時,剛剛說的兩個都需要換。linearlayo...

recyclerView動畫解讀

我彷彿在逗我笑,就算繼承了,還是要呼叫setanimator方法,這樣還是會建立viewholder 那麼,自己給view設定動畫是否可以呢?我們知道,recyclerview是通過notifyitem來改變item的狀態的,這就是傳說中的觀察者模式,那麼我們沒有 notifyitemchanged...

RecyclerView 控制項使用

recyclerview的任務僅限於 和定位螢幕上的列表項,對於列表項的內容顯示我們還需要借助adapter子類和viewholder子類。viewholder的作用是容納view檢視。recyclerview工作需要layoutmanager支援。recyclerview檢視建立好後,要立即交給l...