Reputation: 45140
I am trying to use android Room API to load records from sQlite in pages.
The issue is Paging library is loading entire database into model class and binding it with the adapter which is making UI thread skip frames. It suppose to load 20 records and then keep on adding more when required
This is my view model class
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();
}
}
Paged adapter
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));
}
}
}
Binding with recycler View:
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
Any idea what I am missing.
Upvotes: 9
Views: 6465
Reputation: 64
You should call userUserAdapter.submitList(pagedList)
.
setList()
is used for RecyclerView.Adapter
not for PagedListAdapter
.
Upvotes: 1
Reputation: 923
try userUserAdapter.setList(pagedList); put out observe . observe use listner list change . You . You need to initialize the list and set up recyclerview normally . The object list should be included in the pageAdapter in the usual way
Upvotes: 1
Reputation: 6389
By the paging implementation, your result count should indeed be the full size of the query (200), as you configured to do so, the RecyclerView
will receive placeholders null
for the views which data is not ready yet. This is intended for when you want to show the whole list views but only bind the content of it when the data is available. But your RecyclerView
should not call onCreateViewHolder
and onBindViewHolder
for the entire count unless it is visible.
Check (put a breakpoint) the method onMeasure
or onLayout
on your RecyclerView
to see if the method is not returning a bigger height than expected (probably the expected is something around the size of your screen). Sometimes the actual height of RecyclerView
is much bigger than the screen and the adapter call onBindViewHolder()
for the total number of items because it's "visible" to it instead of the number we can see. This would trigger the DataSource
to query the database and bind the views before you want.
Upvotes: 1