我有一个类似聊天的活动,我使用带有PagedListAdaper的RecyclerView来加载一堆消息。我使用PositionalDataSource加载数据。加载它的自我工作正常但是当我发送消息时,我使我的数据源无效并且列表被重新制作。 我的问题是,当它发生时会闪烁:
我尝试添加setHasStableIds(true)并重写getItemId,它可以在一个简单的适配器上工作,但它似乎在这里工作。我似乎也无法将项添加到getCurrentList(),因为它不受支持。另外,我没有使用数据库,只是向服务器发出请求。
所以我的问题是,除了使数据源无效之外,还有更好的方法吗?有没有办法阻止列表在发送消息时闪烁?或者这个图书馆不适合我的聊天活动?
修改:
我的差异回调
private var mHelper: PagedListAdapterHelper<MessageModel>? = null
init {
mHelper = PagedListAdapterHelper(this, DIFF_CALLBACK)
setHasStableIds(true)
}
fun setList(pagedList: PagedList<MessageModel>) {
pagedList.addWeakCallback(pagedList.snapshot(), object:PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {
}
override fun onInserted(position: Int, count: Int) {
mHelper?.setList(pagedList)
}
override fun onRemoved(position: Int, count: Int) {
}
})
}
编辑2我修好了:
所以我设法通过使用PagedListAdapterHelper并在加载项目后设置它的列表来修复它:
db.test.aggregate([
{ $match:{ "attributes.id" : "WEBAKKUNDE", "attributes.value":"1" } },
{ $unwind: "$attributes" },
{ $match: { "attributes.id": "GR1" } },
])
答案 0 :(得分:1)
简短回答:确保在callback
中同步调用PositionalDataSource<T>.loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<T> callback)
loadInitial
,而不将其包装在某种异步成功处理程序中。
说明:
闪烁可能是由初始加载中的异步加载引起的,即PositionalDataSource<T>.loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<T> callback)
。
执行此操作时会发生以下情况:
您的数据源无效,这会导致创建新的PagedList
(使用LivePagedListBuilder
创建时)。这个新创建的分页列表将传递给您的适配器,但它仍然是空的,因为您没有直接在初始加载中调用回调。只要调用回调,这将导致一个空列表。这最终会导致闪烁效应。
答案 1 :(得分:1)
您可以禁用项目动画。
mRecyclerView.setItemAnimator(null);
答案 2 :(得分:0)
PagedListAdapterHelper在分页组件中已弃用,因此我们应使用AsyncPagedListDiffer代替它。
代码示例:
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);
}
};
答案 3 :(得分:0)
您应在loadInitial
和loadAfter
中使用同步,即:
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!");
}
答案 4 :(得分:0)
我们将 paging library 3
与 room
一起使用。在我们在数据库上写了一些下一页数据后,我们得到了闪烁、闪烁和滚动的效果。因为我们将 PagingConfig
的 initialLoadSize
设置为与 pageSize
不同。我们已经开始对它们使用相同的值,我们的问题已得到解决。