I'm using the Paging library.
Currently, I want to sort (using SortList) the items by the description in PagedListAdapter but I have not figured out how to do it.
How to sort elements when using a PagedListAdapter? Thank you.
I'm using the Paging library.
Currently, I want to sort (using SortList) the items by the description in PagedListAdapter but I have not figured out how to do it.
How to sort elements when using a PagedListAdapter? Thank you.
I faced this problem too, and was surprised that PagedList
doesn't seem to have a straightforward way to sort items. Here's how I achieved the effect I needed using DataSource's mapByPage()
:
/** sorts MyItems by timestamp in descending order */
private fun DataSource.Factory<Long, MyItem>.sortByDescTime(): DataSource.Factory<Long, MyItem> {
return mapByPage {
myItemsList.sortedWith(compareByDescending { item -> item.timeStamp })
}
}
i.e, the input of mapByPage()
should be your sorting function (depends on your setup, mine uses the Kotlin extensions & lambda syntax to sort the items in the target list - using Collections.sortedWith()
)
And then, used my extension function on the data source to sort the fetched items:
fun fetchItems(userId: Long): LiveData<PagedList<MyItem>> {
val itemDataSource = itemAPIService.getItems(userId).sortByDescTime()
val itemPagedList = LivePagedListBuilder(itemDataSource, 10).build()
return itemPagedList
}
you need to use MediatorLiveData here. though below code is in java, it should serve the basic purpose. In Your ViewModel add both
public LiveData<PagedList<Customer>> customerList;
public MediatorLiveData<PagedList<Customer>> customerListMediator;
then first fetch liveData, that is, customerList in my case
customerList = new LivePagedListBuilder<>(mAppRepository.getCustomers(new SimpleSQLiteQuery(dynamicQuery)),1).build();
after that use the mediatorLiveData:-
customerListMediator.addSource(customerList, new Observer<PagedList<Customer>>() {
@Override
public void onChanged(@Nullable PagedList<Customer> customers) {
customerListMediator.setValue(customers);
}
});
And in your recyclerview, don't use LiveData list, instead use mediatorLiveData, in my case customerListMediator. like below:-
mViewModel.customerListMediator.observe(this, customers -> {
mViewModel.customerListAdapter.submitList(customers);
Toast.makeText(this, "list updated.", Toast.LENGTH_SHORT).show();
});
mapByPage() function works, but has side effects as you would need to "prepend" the next page items in the PagedList to have the desired effect.
Using Room @Dao and SQL sorting capabilities you can do something like this, which seems more performant as it releases sorting operations from the UI components:
@Dao
public interface MyItemDao{
enum SORT_OPT {
LABEL_ASC, LABEL_DESC, PRICE_ASC, PRICE_DESC, RATING_ASC, RATING_DESC
}
@Update
void update(ItemEntity itemEntity);
@Delete
void delete(ItemEntity itemEntity);
@Query("DELETE FROM item_table")
void deleteAll();
@Query("SELECT * FROM item_table ORDER BY price ASC")
@Transaction
DataSource.Factory<Integer, ItemEntity> getProductsOrderByPriceAsc();
@Query("SELECT * FROM item_table ORDER BY price DESC")
@Transaction
DataSource.Factory<Integer, ItemEntity> getProductsOrderByPriceDesc();
@Query("SELECT * FROM item_table ORDER BY label ASC")
@Transaction
DataSource.Factory<Integer, ItemEntity> getProductsOrderByLabelAsc();
@Query("SELECT * FROM item_table ORDER BY label DESC")
@Transaction
DataSource.Factory<Integer, ItemEntity> getProductsOrderByLabelDesc();
@Query("SELECT * FROM product_table ORDER BY totalRating ASC")
@Transaction
DataSource.Factory<Integer, ItemEntity> getProductsOrderByRatingAsc();
@Query("SELECT * FROM product_table ORDER BY totalRating DESC")
@Transaction
DataSource.Factory<Integer, ItemEntity> getProductsOrderByRatingDesc();
default DataSource.Factory<Integer, ItemEntity> getSortedProducts(SORT_OPT sortOptions) {
switch (sortOptions) {
case LABEL_ASC:
return getProductsOrderByLabelAsc();
case LABEL_DESC:
return getProductsOrderByLabelDesc();
case PRICE_ASC:
return getProductsOrderByPriceAsc();
case PRICE_DESC:
return getProductsOrderByPriceDesc();
case RATING_ASC:
return getProductsOrderByRatingAsc();
case RATING_DESC:
return getProductsOrderByRatingDesc();
default:
return null;
}
}
As you can notice the most important method here is: default DataSource.Factory<Integer, ItemEntity> getSortedProducts(SORT_OPT sortOptions)
You can store you sort value in sharedPreferences and load it from there.
© 2022 - 2024 — McMap. All rights reserved.