RecyclerView 局部更新

    技术2022-07-13  65

    如果列表中的某个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 时,就会出现问题。

    KOTLINJAVA

        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 应尝试预取该行中的内容。

    Processed: 0.014, SQL: 9