How to sort recyclerview by lowest number / String Android Studio

There are some options for implementing sorting in a RecyclerView. Of course it is possible to rely on Comparable<T> and Comparator<T> interfaces but, as you mentioned, it is also possible to exploit SortedList<T> class defined in Android SDK.

Purpose of SortedList<T> is simplifying sorting of elements in a RecyclerView, allowing you to intercept significant events like "new item added", "item removed" and so on.

In your case you can proceed as follows:

  1. Define a Person class for wrapping rank and name. Please notice that in this version I'm assuming to have integer values for rank, but it's quite easy to move to decimal value.

    class Person {
    
        private String rank;
        private String name;
    
        public Person(String rank, String name) {
            this.rank = rank;
            this.name = name;
        }
    
        // getters and setters here
    
    }
    
  2. Define an Activity where to build RecyclerView and corresponding adapter. In this example I've included a FloatingActionButton for inserting new random Persons. As you can see, when creating a new Person, method addPerson is invoked on the adapter. Its effect will be to update the RecyclerView, sorting it according to criteria defined within the adapter itself (see point 3).

    public class SortPersonsActivity extends AppCompatActivity {
    
        private List<Person> mPersons;
    
        private SortPersonsAdapter mPersonsAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_persons_list);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
            mPersons = new ArrayList<>();
            mPersons.add(new Person("1\nrank", "James Kub"));
            mPersons.add(new Person("2\nrank", "Peter Hanly"));
            mPersons.add(new Person("3\nrank", "Josh Penny"));
            mPersons.add(new Person("1\nrank", "Danny Jackson"));
            mPersons.add(new Person("3\nrank", "Brad Black"));
    
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.lst_items);
            recyclerView.setLayoutManager(getLayoutManager());
            mPersonsAdapter = new SortPersonsAdapter(this, mPersons);
            recyclerView.setAdapter(mPersonsAdapter);
    
            FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // building new fake person
                    Person person = new Person(
                            buildRandomInt(10) + "\nrank",
                            buildRandomName(5) + " " + buildRandomName(5));
                    // let's keep also basic list updated
                    mPersons.add(person);
                    // let's update adapter
                    mPersonsAdapter.addPerson(person);
                }
            });
        }
    
        private RecyclerView.LayoutManager getLayoutManager() {
            LinearLayoutManager llm = new LinearLayoutManager(this);
            llm.setOrientation(LinearLayoutManager.VERTICAL);
            return llm;
        }
    
        // support method for random names and ranks here
    
    }
    
  3. Implement a RecyclerView Adapter relying on SortedList<Person>. Here it's important to notice that all Persons are inserted into a SortedList<Person>. Creating a SortedList<T> requires a Callback to be defined for intercepting events as well as for defining sorting criteria. In our case, as you can see, compare method defines criteria for sorting Persons while onInserted method defines what to do when a new Person is inserted (notify a data set change for updating RecyclerView in this case). Please notice also implementation of addPerson method described at point 2. It just adds a Person to the SortedList, because the logic for updating RecyclerView is embedded into the Callback method onInserted mentioned before.

    class SortPersonsAdapter extends RecyclerView.Adapter<SortPersonsAdapter.PersonViewHolder> {
    
        protected static class PersonViewHolder extends RecyclerView.ViewHolder {
    
            View layout;
            TextView txt_rank;
            TextView txt_full_name;
    
            public PersonViewHolder(View itemView) {
                super(itemView);
                layout = itemView;
                txt_rank = (TextView) itemView.findViewById(R.id.txt_rank);
                txt_full_name = (TextView) itemView.findViewById(R.id.txt_full_name);
            }
    
        }
    
        private Context mContext;
        private LayoutInflater mLayoutInflater;
    
        private SortedList<Person> mPersons;
    
        public SortPersonsAdapter(Context context, List<Person> persons) {
            mContext = context;
            mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mPersons = new SortedList<>(Person.class, new PersonListCallback());
            mPersons.addAll(persons);
        }
    
        public void addPerson(Person person) {
            mPersons.add(person);
        }
    
        @Override
        public int getItemCount() {
            return mPersons.size();
        }
    
        @Override
        public SortPersonsAdapter.PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = mLayoutInflater.inflate(R.layout.view_person_item, parent, false);
            return new PersonViewHolder(itemView);
        }
    
        @Override
        public void onBindViewHolder(final PersonViewHolder viewHolder, final int position) {
            Person person = mPersons.get(position);
            viewHolder.txt_rank.setText(person.getRank());
            viewHolder.txt_full_name.setText(person.getName());
        }
    
        /**
         * Implementation of callback for getting updates on person list changes.
         */
        private class PersonListCallback extends SortedList.Callback<Person> {
    
            @Override
            public int compare(Person p1, Person p2) {
                String[] rank1 = p1.getStringRank().split("\n");
                String[] rank2 = p2.getStringRank().split("\n");
                int diff = Integer.parseInt(rank1[0]) - Integer.parseInt(rank2[0]);
                return (diff == 0) ? p1.getName().compareTo(p2.getName()) : diff;
            }
    
            @Override
            public void onInserted(int position, int count) {
                notifyItemInserted(position);
            }
    
            @Override
            public void onRemoved(int position, int count) {
                notifyItemRemoved(position);
            }
    
            @Override
            public void onMoved(int fromPosition, int toPosition) {
            }
    
            @Override
            public void onChanged(int position, int count) {
            }
    
            @Override
            public boolean areContentsTheSame(Person oldItem, Person newItem) {
                return false;
            }
    
            @Override
            public boolean areItemsTheSame(Person item1, Person item2) {
                return false;
            }
    
        }
    
    }
    

Hope this could help. Here I've put an implementation for your RecyclerView, in case you need more details on code.


public int compare(Person p1, Person p2) {
   if(p1.getRank() == p2.getRank()){
      return p1.getName().compareTo(p2.getName());
   }else if(p1.getRank() > p2.getRank()){
      return 1;
   }else{
      return -1;
   }
}  

The sorting depends upon what comparison result is returned. You need to return -1, 0, or 1. In the code snippet, all I am doing is checking the ranks first. If they are the same rank, I compare their names which are Strings and every String has a compareTo( ) which lexicographically compares two strings.

If not, we just sort them based on rank.

You can simplify your compare( ) method further by making your Person class implement Comparable interface. That will allow you to use Collections framework goodies out of the box.