1

プロジェクトでページング ライブラリを使用しています。

Activity では、オブザーバーが Room ライブラリが返すデータを監視します。Room のデータが変更されると、UI が更新されます。

RecyclerView の最後までスクロールすると、ページング ライブラリがデータを 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);
        }
    }

DiffUtil

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();
    }
}

MyBoundaryCallback

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();
}
4

1 に答える 1

0

最後に、この問題を解決しました。私の Room エンティティである ItemEntity は、id 型が以前は Long 型 (Reference 型) でしたが、Long 型を long 型 (Basic 型) に変更したところ、すべて問題ありません。

于 2019-11-04T06:17:33.377 に答える