每次我调用无效数据时,都不会使用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
答案 0 :(得分:0)
您可以在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))
有关更多信息,您可以查看完整答案at this post
答案 1 :(得分:0)
尝试覆盖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)
}
答案 2 :(得分:0)
对于其他任何对“ DiffUtil.ItemCallback <*>()”部分有疑问的人,我也遇到了同样的问题。
每次我要刷新数据时,我都会在“ DataSource”对象上调用invalidate(),具体取决于您要继承的数据源的类型,但是有两个回调“ areItemsTheSame()”和“ areContentsTheSame” ()”没有被触发。
所以我遇到了以下链接:How to stop blinking on recycler view with architecture components paging library
对我来说,窍门是使用“ AsyncPagedListDiffer”以及提交“ pagedList”时。下面的代码在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回调开始起作用