PagedListAdapter не использует DiffUtil при аннулировании данных - PullRequest
4 голосов
/ 19 сентября 2019

Каждый раз, когда я вызываю недействительные данные, мой DIFF_UTIL не используется.Журналы не отображаются, и весь список обновляется новыми данными, заставляя экран перемещать позиции и т. Д. Не знаю, в чем здесь проблема.

У меня PagedListAdapter с LiveData<PagedList<Post>> postList, и я звоню postList.getValue().getDataSource().invalidate(); для обновления моих данных.

У меня есть 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

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

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

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Попробуйте переопределить submitList вашим Adapter

  override fun submitList(list: List<Model>?) {
        val arrayList: ArrayList<Model>?
        if (list != null) {
            arrayList = ArrayList(list)
        } else {
            arrayList = list
        }
        super.submitList(arrayList)
    }

или более элегантным способом

  override fun submitList(list: List<Model>?) {
        super.submitList(if (list != null) ArrayList(list) else null)
    }
0 голосов
/ 26 сентября 2019

Вы можете Ctrl + Click включить submitList функцию и посмотреть, что делает ядро ​​внутри.

public void submitList(final List<T> newList) {
    if (newList == mList) {
        // nothing to do if the newList & old List have the same address in memory 
        return;
    }
....
}

Итак, попробуйте отправить новый список данных и перепроверить

submitList(new ArrayList<>(list))

Для получения дополнительной информации, вы можете проверить полный ответ на этот пост

...