昨天寫了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...