0

I am making a chat app that shows the distance between me and each user.

It looks as follows:

enter image description here

Is there a way to sort this list in a way that it will show the closest first and farest last? now it adds based on the order that it adds to the adapter.

My adapter code is as follows:

public class MapPersonAdapter extends RecyclerView.Adapter<MapPersonAdapter.MyViewHolder> {

    private View mView;
    private List<MapPerson> personsList;
    private FirebaseAuth auth;

    StorageReference storageRef;


    public class MyViewHolder extends RecyclerView.ViewHolder{
        public TextView personName, personDistance;
        public ImageView personProfile;
        public ImageButton personChat;

        public MyViewHolder(View view){
            super(view);
            personName = (TextView) view.findViewById( R.id.tvPersonName );
            personDistance = (TextView) view.findViewById( R.id.tvDistance );
            personProfile = (ImageView) view.findViewById( R.id.ivPersonPic );
            personChat = (ImageButton) view.findViewById( R.id.imageChat );
            mView = view;
        }
    }

    public MapPersonAdapter(List<MapPerson> personsList){
        this.personsList = personsList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View itemView = LayoutInflater.from( parent.getContext() ).inflate( R.layout.activity_map_person,parent,false);
        return new MyViewHolder( itemView );
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        MapPerson mapPerson = personsList.get( position );
        String ID = mapPerson.getPersonID();

        FirebaseFirestore db = FirebaseFirestore.getInstance();
        CollectionReference username = db.collection( "Users" ).document( ID ).collection( "UserData" );
        username.get().addOnCompleteListener( new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        holder.personName.setText( document.getString( "username" ) );
                    }
                } else {
                    Log.d( "Error", "Error getting documents: ", task.getException() );
                }
            }
        } );

        holder.personDistance.setText( mapPerson.getPersonDistance() + " km" );


    @Override
    public int getItemCount(){
        return personsList.size();
    }

}

What im asking is if I can sort somehow based on the value of mapPerson.getPersonDistance().

This adapter is called inside a loop:

for (String PersonID : PeopleAround) {

    DocumentReference docRef = db.collection( "Users" ).document(PersonID).collection( "Location" ).document(PersonID);
    docRef.get().addOnCompleteListener( new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {

                DocumentSnapshot doc2 = task.getResult();

                float distance = CalculateDistance(Lat, Lon);
                if (!PersonID.equals( auth.getUid() )) {
                    if (distance <= Radius) {
                        MapPerson mapPerson = new MapPerson( PersonID, new DecimalFormat( "##.##" ).format( distance ) );
                        personList.add( mapPerson );
                        mapPersonAdapter.notifyDataSetChanged();
                    }
                }
            }
        }
    } );
}
Ben
  • 1,737
  • 2
  • 30
  • 61

1 Answers1

1

Before calling mapPersonAdapter.notifyDataSetChanged();, sort the personList according to the distance, using Comparator and then call notifyDataSetChanged()

Collections.sort(personsList, new Comparator< MapPerson >() {

    public int compare(MapPerson o1, MapPerson o2) {
        // compare two instance of `Score` and return `int` as result.
        return o2.getDistance().compareTo(o1.getDistance());
    }
});
touhid udoy
  • 4,005
  • 2
  • 18
  • 31
  • Im getting that sort is for API>24. any solution for lower API? using 21 atm. – Ben Oct 18 '19 at 15:16
  • the api doesn't matter as far as the final solution goes. You have to sort before loading the list. You can't do it afterwards. – John Lord Oct 18 '19 at 15:23
  • @Ben ignore the last part where java 8 is used. Use the first part of the solution – touhid udoy Oct 18 '19 at 15:25
  • I've added the snippet as your requirement. you should also save distance in `double` value and use that to compare between two persons – touhid udoy Oct 18 '19 at 15:29
  • 1
    Thank you very much mate! I just added in the end Collection.reverse(personList) to show the closest first =] – Ben Oct 18 '19 at 15:52