如果列表中的某個item數據發生微小變化而需要更新UI狀態,直接notifyDataSetChanged()的方式會影響性能,今天看到Android官方的列表局部更新方式,分享給大家:
void onNewDataArrived(List<News> news) {
List<News> oldNews = myAdapter.getItems();
DiffResult result = DiffUtil.calculateDiff(new MyCallback(oldNews, news));
myAdapter.setNews(news);
result.dispatchUpdatesTo(myAdapter);
}
//只需將您的 MyCallback 定義爲 DiffUtil.Callback 實現,以通知 DiffUtil 如何檢查您的列表即可。
另外還有RecyclerView的嵌套問題,也有詳細的解釋
RecyclerView:嵌套的 RecyclerView
嵌套 RecyclerView
很常見,對於由水平滾動列表組成的縱向列表(例如 Play 商店主頁面上的應用網格),尤其如此。這種方法效果很好,但它也會導致大量來回移動的視圖。在首次向下滾動頁面時,如果您看到大量內部內容出現擴充,則可能需要檢查內部(水平)RecyclerView 之間是否正在共享 RecyclerView.RecycledViewPool
。默認情況下,每個 RecyclerView 都將有自己的內容池。然而,在屏幕上同時顯示十幾個 itemViews
的情況下,如果所有行都顯示類型相似的視圖,那麼當不同的水平列表無法共享 itemViews
時,就會出現問題。
class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.ViewHolder> { RecyclerView.RecycledViewPool sharedPool = new RecyclerView.RecycledViewPool(); ... @Override public void onCreateViewHolder(ViewGroup parent, int viewType) { // inflate inner item, find innerRecyclerView by ID… LinearLayoutManager innerLLM = new LinearLayoutManager(parent.getContext(), LinearLayoutManager.HORIZONTAL); innerRv.setLayoutManager(innerLLM); innerRv.setRecycledViewPool(sharedPool); return new OuterAdapter.ViewHolder(innerRv); } ...
如果您希望進一步優化,還可以對內部 RecyclerView 的 LinearLayoutManager
調用 setInitialPrefetchItemCount(int)
。例如,如果您始終在某行中顯示 3.5 項內容,請調用 innerLLM.setInitialItemPrefetchCount(4);
。這將向 RecyclerView 表明,當某個水平行即將顯示在屏幕上時,如果界面線程中有空餘時間,RecyclerView 應嘗試預取該行中的內容。