我在我的项目中使用分页库。
在 Activity 中,观察者观察 Room 库返回的数据,当 Room 的数据发生变化时,UI 会更新。
当我滚动到 RecyclerView 的末尾时,Paging 库开始将数据加载到 Room 中。
但是 RecyclerView 的列表刷新不正确并滚动到上一个位置。
我的代码有什么问题?
PagingItemRepository repository = new PagingItemRepository(FindDatabase.getInstance(PagingListActivity.this).pagingItemDao());
repository.getAllItems().observe(this, new Observer<PagedList<ItemEntity>>() {
@Override
public void onChanged(PagedList<ItemEntity> itemEntities) {
adapter.submitList(itemEntities);
}
});
适配器
class PagingListAdapter extends PagedListAdapter<ItemEntity, ItemHolder> {
protected PagingListAdapter() {
super(DIFF_CALLBACK);
}
protected PagingListAdapter(@NonNull DiffUtil.ItemCallback<ItemEntity> diffCallback) {
super(diffCallback);
}
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ItemHolder(LayoutInflater.from(PagingListActivity.this).inflate(R.layout.list_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull ItemHolder holder, int position) {
ItemEntity entity = getItem(position);
if (entity != null) {
String value = entity.getText();
holder.textView.setText(value);
}
}
}
class ItemHolder extends RecyclerView.ViewHolder {
TextView textView;
public ItemHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text);
}
}
扩散
private static DiffUtil.ItemCallback<ItemEntity> DIFF_CALLBACK =
new DiffUtil.ItemCallback<ItemEntity>() {
// Concert details may have changed if reloaded from the database,
// but ID is fixed.
@Override
public boolean areItemsTheSame(ItemEntity oldEntity, ItemEntity newEntity) {
return oldEntity.getId() == newEntity.getId();
}
@Override
public boolean areContentsTheSame(ItemEntity oldEntity,
ItemEntity newEntity) {
return oldEntity.equals(newEntity);
}
};
PagingItemRepository
public class PagingItemRepository {
private PagingItemDao itemDao;
LivePagedListBuilder<Integer, ItemEntity> builder;
public PagingItemRepository(PagingItemDao itemDao) {
this.itemDao = itemDao;
DataSource.Factory<Integer, ItemEntity> factory = itemDao.getAllItems();
PagedList.Config config = new PagedList.Config.Builder().
setPageSize(60).
setPrefetchDistance(0).
setEnablePlaceholders(true).
setInitialLoadSizeHint(120).
//setMaxSize(200).
build();
builder = new LivePagedListBuilder<>(factory, config);
builder.setBoundaryCallback(new MyBoundaryCallback(itemDao));
}
LiveData<PagedList<ItemEntity>> getAllItems() {
return builder.build();
}
}
我的边界回调
public static class MyBoundaryCallback extends PagedList.BoundaryCallback<ItemEntity> {
private PagingItemDao itemDao;
public MyBoundaryCallback(PagingItemDao itemDao) {
this.itemDao = itemDao;
}
@Override
public void onZeroItemsLoaded() {
new Thread(new Runnable() {
@Override
public void run() {
final List<ItemEntity> entities = new ArrayList<>();
for (int i = 0; i < 30; i++) {
count++;
ItemEntity entity = new ItemEntity();
entity.setText(count + "");
entities.add(entity);
}
itemDao.addItems(entities);
}
}).start();
}
@Override
public void onItemAtFrontLoaded(@NonNull ItemEntity itemAtFront) {
}
@Override
public void onItemAtEndLoaded(@NonNull ItemEntity itemAtEnd) {
final Long id = itemAtEnd.getId();
new Thread(new Runnable() {
@Override
public void run() {
if (id >= 530) {
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
final List<ItemEntity> entities = new ArrayList<>();
for (int i = 0; i < 50; i++) {
count++;
ItemEntity entity = new ItemEntity();
entity.setText(count + "");
entities.add(entity);
}
itemDao.addItems(entities);
}
}).start();
}
}
PagingItemDao
@Dao
public interface PagingItemDao {
@Query("select * from item")
DataSource.Factory<Integer, ItemEntity> getAllItems();
@Insert
void addItems(List<ItemEntity> entities);
@Query("delete from item")
void delete();
}