24.2 版本的 support library 裡引入了一個叫做 DiffUtil 的類,它讓重新整理 RecyclerView.Adapter 變得更簡單。在 27.0 版本的 leanback support library 裡面又增加了一個支援 ArrayObjectAdapter 的抽象 DiffUtil
。
ArrayObjectAdapter 有一個新的方法叫做 setItems(final List itemList, final DiffCallback callback),它接收一個新的類叫做 DiffCallback。DiffCallback
看上去很像 DiffUtil.Callback,只是少了幾個方法。
public abstract class DiffCallback<Value> {
public abstract boolean areItemsTheSame(@NonNull Value oldItem,
@NonNull Value newItem);
public abstract boolean areContentsTheSame(@NonNull Value oldItem,
@NonNull Value newItem);
@SuppressWarnings("WeakerAccess")
public Object getChangePayload(@NonNull Value oldItem, @NonNull Value newItem) {
return null;
}
}
複製程式碼
獲取 list 大小的方法不見了!這個 adapter 裡的 setItems()
方法知道舊的資料和新的資料,當 adapter 建立 DiffUtil.Callback
的時候,它重寫了 getOldListSize() 和 getNewListSize() 方法,讓你能夠專心比較 list 中資料的異同。
val diffCallback = object : DiffCallback<DummyItem>() {
override fun areItemsTheSame(oldItem: DummyItem,
newItem: DummyItem): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: DummyItem,
newItem: DummyItem): Boolean =
oldItem == newItem
}
itemsAdapter.setItems(randomItems(), diffCallback)
複製程式碼
Adapter 重新整理 item 並且播放動畫。
ArrayObjectAdapter 會播放合適的動畫。
你不一定要呼叫帶有 DiffCallback
的 setItems()
方法。如果你不支援 DiffCallback
,adapter 會清空當前的 item 並且新增所有新的 item,這可能導致你的內容在螢幕上閃一下。
這一行裡的內容會在刪除和新增 item 的時候閃動。
通過檢視 setItems()
的原始碼,我們可以發現 ArrayObjectAdapter
是如何抽象 DiffUtil
裡的樣板方法,給開發者提供一個更整潔的 API。
ArrayObjectAdapter 裡面 setItems()
方法的部分原始碼。
如果你想嘗試使用 DiffCallback
,可以從參考這篇 gist 開始。
如果你在開發 Android TV 平臺上的應用,我很想了解開發過程中你最喜歡的是什麼,還有你的痛點是什麼。如果你想繼續這個話題,請在 Twitter 上給我評論或者留言。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。