NiceToMytyuk
NiceToMytyuk

Reputation: 4277

How to sort the RecyclerView on each new item?

I have a RecyclerView on which i add items from another RecyclerView, each item has a property called "TYPE" and it's value can be "FASE1", "FASE2" and up to "FASE8".

When a new item is added to that list or removed i need to sort it based on the TYPE values.

So all items has to be sorted like ITEM1 FASE1 > ITEM2 FASE2 ....

Till now i was just adding or removing items from the RecyclerView like the following:

Here is the code from RecyclerView Adapter of the RecyclerView which adds items to the other RecyclerView.

private void addOrRemove(int position, boolean add) {
        // piattiItems is a reference to ArrayList<ItemPTERM> from the Adapter of the RecyclerView where i have to add the items
        Item prodotto = mFilteredList.get(position); // getting item from current RecyclerView
        ItemPTERM prodottoAggiunto = piattiAdapter.getItemByCode(prodotto.getCodice()); // cheking if there is yet the same item in the RecyclerView where i have to add it
   if (add) {
        piattiItems.add(nuovoProdotto(prodotto)); // adding new item
        piattiAdapter.notifyItemInserted(size);
        recyclerPiatti.scrollToPosition(size);
   }else {
        piattiItems.remove(prodottoAggiunto); // removing item
        piattiAdapter.notifyItemRemoved(position);
   }
} 

Upvotes: 0

Views: 895

Answers (2)

Sam Chen
Sam Chen

Reputation: 8847

The idea is:

  1. RecyclerView should just be responsible for displaying your data, it shouldn't know the order of your List data.

  2. Your List data should be responsible for the order.


So, after you add new item to your RecylerView, first update/resort your List, then call notifyDataSetChanged() on the Adapter object. Or just call sumitList() if you're using ListAdapter with DiffUtil, which will just update the changed items rather than updating the whole List like RecyclerView.Adapter.

Upvotes: 1

Nicola Fanelli
Nicola Fanelli

Reputation: 552

It can be done by defining an order relation among the ItemPTERMs by implementing the Comparable<ItemPTERM> interface with ItemPTERM or by creating a Comparator that implements Comparator<ItemPTERM>.

In the latter, you should implement the compare method. I'm supposing that "TYPE" is an Enum to make things simpler; by the way if it's a String you should implement a specific algorithm for your goal.

When comparator is ready, you can add elements to piattiItems as always and call Collections.sort(piattiItems, comparator) to sort the ArrayList. Now you can get the index of the newly added item and use it to tell your RecyclerView the position of this item. RecyclerView will do the rest by showing the item at the correct position!

private Comparator<ItemPTERM> mComparator = new Comparator<>(){
    @Override
    public int compare(ItemPTERM o1, ItemPTERM o2) {
        return o1.type.compareTo(o2.type); // supposing that type is enum
    }
}

private void addOrRemove(int position, boolean add) {
        Item prodotto = mFilteredList.get(position);
        ItemPTERM prodottoAggiunto = piattiAdapter.getItemByCode(prodotto.getCodice());
   if (add) {
        ItemPTERM newItem = nuovoProdotto(prodotto);
        piattiItems.add(newItem);
        Collections.sort(piattiItems, mComparator); // sorts after adding new element
        int index = piattiItems.indexOf(newItem); // gets the index of the newly added item
        piattiAdapter.notifyItemInserted(index); // uses the index to tell the position to the RecyclerView
        recyclerPiatti.scrollToPosition(index);
   }else {
        piattiItems.remove(prodottoAggiunto);
        piattiAdapter.notifyItemRemoved(position);
   }
}

Upvotes: 1

Related Questions