PagedListAdapter不在无效数据上使用DiffUtil [英] PagedListAdapter Not Using DiffUtil On invalidate Data

查看:103
本文介绍了PagedListAdapter不在无效数据上使用DiffUtil的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次我调用无效数据时,都不会使用DIFF_UTIL.日志未显示,并且整个列表已更新为新数据,导致屏幕移动了位置等.不知道问题出在哪里.

Every time I call invalidate data my DIFF_UTIL is not used. The logs are not shown and the entire list is updated with new data causing the screen to move positions etc. Not sure what the issue is here.

我有一个PagedListAdapter和一个LiveData<PagedList<Post>> postList,我打电话给postList.getValue().getDataSource().invalidate();刷新我的数据.

I have PagedListAdapter with a LiveData<PagedList<Post>> postList and I call postList.getValue().getDataSource().invalidate(); to refresh my data.

我有DIFF_UTIL

 public static DiffUtil.ItemCallback<Post> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<Post>() {

                @Override
                public boolean areItemsTheSame(Post oldItem, Post newItem) {
                    Log.d(TAG, "areItemsTheSame with result: "
                            + (oldItem.getId() == newItem.getId()));
                    Log.d(TAG, "areItemsTheSame Old Item is: " + oldItem.toString());
                    Log.d(TAG, "areItemsTheSame New Item is: " + newItem.toString());
                    return oldItem.getId() == newItem.getId();
                }

                @Override
                public boolean areContentsTheSame(Post oldItem, Post newItem) {
                    Log.d(TAG, "areContentsTheSame with result: " + oldItem.equals(newItem));
                    Log.d(TAG, "areContentsTheSame Old Item is: " + oldItem.toString());
                    Log.d(TAG, "areContentsTheSame New Item is: " + newItem.toString());
                    return oldItem.equals(newItem);
                }
            };

我有我的适配器:

import...

public class PostAdapter extends PagedListAdapter<Post, PostAdapter.PostViewHolder> {
    interface...

    protected PostAdapter() {
        super(DIFF_CALLBACK);
    }

    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater
                .from(parent.getContext()).inflate(R.layout.feed_card_view, parent, false);
        return new PostViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
        Post post = getItem(position);
        Log.d(TAG, "onBindViewHolder with position: " + position);
        if (post != null) {
            setUpPost(holder, post);
            Log.d(TAG, "onBindViewHolder with post: " + post.toString());
        } else {
            holder.clear();
            Log.d(TAG, "onBindViewHolder post is null");
        }
    }

    private void setUpPost(@NonNull PostViewHolder holder, @NonNull Post post) {
       ...do some things to set up post
    }

    class PostViewHolder extends RecyclerView.ViewHolder {
       Buttons etc..

        public PostViewHolder(View itemView) {
            super(itemView);
            button b = findviewbyid...
        }

        void clear() {
            button.invalidate()..
        }
    }
}

我的片段

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_feed, container, false);
        feedViewModel = ViewModelProviders.of(getActivity()).get(FeedViewModel.class);

        RecyclerView recyclerView = v.findViewById(R.id.post_list);
        PostAdapter adapter = new PostAdapter(this);

        feedViewModel.postList.observe(this, pagedList -> {
            try {
                //refresh current list
                adapter.submitList(pagedList);
            } catch (Exception e) {}
        });


        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));

        return v;
    }

我的ViewModel

My ViewModel

public class FeedViewModel extends AndroidViewModel {
    private LiveData<PagedList<Post>> postList;
    private FeedRepository feedRepository;

    public FeedViewModel(final Application application) {
        super(application);
        feedRepository = new FeedRepository();
        postList = feedRepository.getPosts();
    }

    public void refreshPosts() {
        feedRepository.refreshPosts();
    }

    ... 

    public LiveData<PagedList<Post>> getPostList() {
        return postList;
    }
}

存储库

public class FeedRepository {
    private LiveData<PagedList<Post>> postList;

    private static final String TAG = FeedRepository.class.getName();
    private static final int NUMBER_OF_POSTS_TO_GET = 2;
    private static final boolean ENABLE_POST_PAGE_HOLDER = true;
    private static final int NUMBER_OF_POSTS_TO_GET_IN_ADVANCE = 50;
    private static final int NUMBER_OF_POSTS_ON_FIRST_LOAD = 20;

    public FeedRepository() {
        //Prefs on PagedList
        PagedList.Config myPagingConfig = new PagedList.Config.Builder()
                .setPageSize(NUMBER_OF_POSTS_TO_GET)
                .setEnablePlaceholders(ENABLE_POST_PAGE_HOLDER)
                .setPrefetchDistance(NUMBER_OF_POSTS_TO_GET_IN_ADVANCE)
                .setInitialLoadSizeHint(NUMBER_OF_POSTS_ON_FIRST_LOAD)
                .build();

        PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory();

        postList = new LivePagedListBuilder(
                postDataSourceFactory, myPagingConfig).build();
    }

    public LiveData<PagedList<Post>> getPosts() {
        return postList;
    }

    public void refreshPosts() {
        Log.d(TAG, "refreshPosts, invalidateDataSources()");
        postList.getValue().getDataSource().invalidate();
    }
}

DataSource.Factory

DataSource.Factory

public class PostDataSourceFactory extends DataSource.Factory<String, Post> {
   public PostDataSourceFactory() {
    }

    @NonNull
    @Override
    public DataSource<String, Post> create() {
        PostDataSource postDataSource = new PostDataSource();
        return postDataSource;
    }
}

我在这里遵循google示例: https://developer.android .com/reference/android/arch/paging/PagedListAdapter.html

I following the google example here: https://developer.android.com/reference/android/arch/paging/PagedListAdapter.html

推荐答案

对于其他与"DiffUtil.ItemCallback< *(>)()"有问题的人部分,我遇到了同样的问题.

For anyone else having issue with the "DiffUtil.ItemCallback<*>()" part, I was having the same problem.

每次我想刷新我的数据时,我都会在"DataSource"数据块上调用invalidate().对象,具体取决于您要继承的数据源的类型,但是2个回调"areItemsTheSame()" & "areContentsTheSame()";没有被触发.

Every time I wanted to refresh my data, I would call invalidate() on the "DataSource" object, depending on the type of what data source you are inhering from, but the 2 callbacks "areItemsTheSame()" & "areContentsTheSame()" were not getting triggered.

所以我遇到了以下链接:

So I came across this link: How to stop blinking on recycler view with architecture components paging library

对我来说,诀窍是使用"AsyncPagedListDiffer"以及在提交"pagedList"时.下面的代码在Kotlin中.

What did the trick for me was to use an "AsyncPagedListDiffer" and when submitting the "pagedList". The below code is in Kotlin.

fun submitList(pagedList: PagedList<*?>) {
  pagedList.addWeakCallback(pagedList.snapshot(), object : PagedList.Callback() {
    override fun onChanged(position: Int, count: Int) {
    }

    override fun onInserted(position: Int, count: Int) {
      mDiffer.submitList(pagedList)
    }

    override fun onRemoved(position: Int, count: Int) {
    }

  })
}

通过添加这些内容,我的diff回调开始起作用

By adding this things my diff callback started to work

这篇关于PagedListAdapter不在无效数据上使用DiffUtil的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆