我正在尝试使用 android Room API 在页面中从 sQlite 加载记录。
问题是 Paging 库正在将整个数据库加载到模型类中并将其与使 UI 线程跳帧的适配器绑定(bind)。它假设加载 20 条记录,然后在需要时继续添加更多记录
这是我的 View 模型类
public class UserViewModel extends ViewModel {
public LiveData<PagedList<User>> userList;
public UserViewModel() {
}
public void init(UserDao userDao) {
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder()).setEnablePlaceholders(true)
.setPrefetchDistance(10)
.setPageSize(20).build();
userList = (new LivePagedListBuilder(userDao.usersByFirstName(),
pagedListConfig))
.build();
}
}
分页适配器
public class UserAdapter extends PagedListAdapter<User, UserAdapter.UserItemViewHolder> {
protected UserAdapter() {
super(User.DIFF_CALLBACK);
}
@Override
public UserItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.item_user_list, parent, false);
return new UserItemViewHolder(view);
}
@Override
public void onBindViewHolder(UserItemViewHolder holder, int position) {
User user= getItem(position);
if(user!=null) {
holder.bindTo(user);
}
}
static class UserItemViewHolder extends RecyclerView.ViewHolder {
TextView userName, userId;
public UserItemViewHolder(View itemView) {
super(itemView);
userId = itemView.findViewById(R.id.userId);
userName = itemView.findViewById(R.id.userName);
}
public void bindTo(User user) {
userName.setText(user.firstName);
userId.setText(String.valueOf(user.userId));
}
}
}
与回收者 View 绑定(bind):
UserViewModel viewModel =
ViewModelProviders
.of(this)
.get(UserViewModel.class);
viewModel.init(userDao);
final UserAdapter userUserAdapter = new UserAdapter();
viewModel.userList.observe(this, pagedList -> {
Toast.makeText(this, "Page " + pagedList.size(), Toast.LENGTH_SHORT).show();
Log.e("Paging ", "Page " + pagedList.size());
userUserAdapter.setList(pagedList);
});
recyclerView.setAdapter(userUserAdapter);
02-18 10:19:40.409 15310-15310/com.androidkt.archpaging E/Paging: Page 200
知道我错过了什么。
最佳答案
通过分页实现,您的结果计数确实应该是查询的完整大小 (200),正如您配置的那样,RecyclerView
将接收占位符 null
对于数据尚未准备好的 View 。这适用于您想要显示整个 ListView 但仅在数据可用时绑定(bind)其内容的情况。但是你的 RecyclerView
不应该为整个计数调用 onCreateViewHolder
和 onBindViewHolder
除非它是可见的。
检查(设置断点)RecyclerView
上的方法 onMeasure
或 onLayout
以查看该方法是否未返回比预期的(可能预期的是屏幕大小左右的东西)。有时 RecyclerView
的实际高度比屏幕大得多,适配器调用 onBindViewHolder()
获取项目总数,因为它对它“可见”而不是数量我们可以看到。这将触发 DataSource
查询数据库并在您需要之前绑定(bind) View 。
关于Android 房间分页不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48848610/