How to stop blinking on recycler view with architecture components paging library

后端 未结 5 1180
囚心锁ツ
囚心锁ツ 2021-02-05 08:02

I have a chat-like activity where I am using a RecyclerView with a PagedListAdaper to load a bunch of messages. I\'m using a PositionalDataSource to load the data. The loading i

相关标签:
5条回答
  • 2021-02-05 08:49

    you should use sync in loadInitial and loadAfter, ie:

    mLoadState.postValue(NetworkState.Loading);
    try {
        mLoadState.postValue(NetworkState.DONE);
        ResultMessage<List<Achievement>> info = call.execute().body();
        if (info != null && info.isSuccess()) {
            List<Achievement> list = info.getData();
            callback.onResult(list, null, FIRST_PAGE + 1);
        }
    } catch (IOException e) {
        mLoadState.postValue(NetworkState.ERROR);
        mRetry.postValue(() -> loadInitial(params, callback));
        Log.d(TAG, "fail!");
    }
    
    0 讨论(0)
  • 2021-02-05 08:50

    PagedListAdapterHelper deprecated in Paging Component so we should use AsyncPagedListDiffer instead of it.

    Code example:

        import android.arch.paging.AsyncPagedListDiffer;
        import android.arch.paging.PagedList;
        import android.arch.paging.PagedListAdapter;
        import android.support.annotation.NonNull;
        import android.support.v7.util.DiffUtil;
        import android.view.LayoutInflater;
        import android.view.ViewGroup;
    
    
        public class PagedItemsArrayAdapter extends PagedListAdapter<Item, MyViewHolder> {
    
                private final AsyncPagedListDiffer<Item> mDiffer;
    
                public PagedItemsArrayAdapter() {
                    super(DIFF_CALLBACK);
                    mDiffer = new AsyncPagedListDiffer<>(this, DIFF_CALLBACK);
                    setHasStableIds(true);
                }
    
                @Override
                public long getItemId(int position) {
                   Item item = mDiffer.getItem(position);
                   return item.id;
                }
    
                @Override
                public int getItemCount() {
                    return mDiffer.getItemCount();
                }
    
                @Override
                public void submitList(PagedList<Item> pagedList) {
    
                    pagedList.addWeakCallback(pagedList.snapshot(), new PagedList.Callback() {
                        @Override
                        public void onChanged(int position, int count) {
                        }
    
                        @Override
                        public void onInserted(int position, int count) {
                            mDiffer.submitList(pagedList);
                        }
    
                        @Override
                        public void onRemoved(int position, int count) {
    
                        }
                    });
    
                }
    
    
                @Override
                public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int position) {
                       Item item = mDiffer.getItem(position);
                       viewHolder.onBind(item); 
                }
    
                private static DiffUtil.ItemCallback<Item> DIFF_CALLBACK = new DiffUtil.ItemCallback<Item>() {
                    @Override
                    public boolean areItemsTheSame(@NonNull Item oldItem, @NonNull Item newItem) {
                        return oldItem.getId() == newItem.getId();
                    }
    
                    @Override
                    public boolean areContentsTheSame(@NonNull Item oldItem, @NonNull Item newItem) {
                        return oldItem.equals(newItem);
                    }
                };
    
    0 讨论(0)
  • 2021-02-05 09:00

    You can disable the item animations.

    mRecyclerView.setItemAnimator(null);
    
    0 讨论(0)
  • Short answer: make sure to call the callback of PositionalDataSource<T>.loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<T> callback) synchronously in loadInitial without wrapping it in some kind of asynchronous success handler.

    Explanation:

    Blinking can be caused by asynchronous loads in your initial load i.e. in PositionalDataSource<T>.loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<T> callback).

    The following will happen when you do so:

    Your data source gets invalidated which leads to the creation of a new PagedList (when created with LivePagedListBuilder). This newly created paged list will be passed to your adapter but it is still empty because you didn't call the callback directly in your initial load. This will lead to an empty list for as long as it takes for your callback to be called. This ultimately results in a flicker effect.

    0 讨论(0)
  • 2021-02-05 09:03

    We are using paging library 3 with room. We were getting flickering, blinking and scrolling effects after we wrote some next page data on database. Because we set the PagingConfig's initialLoadSize different than pageSize. We have started to use same value for both of them and our problem has been fixed.

    0 讨论(0)
提交回复
热议问题