1

I have a listview which I populate from the database. The list shows available food with the following details:

  1. The time of food preparation
  2. Rating of restaurant
  3. Lat/ Long of restaurant
  4. Quantity of food.

Now I want to sort the listview based on these four items. I am using a ArrayList<HashMap<String, String>> and an adapter extending the baseadapter.

I have seen many answers on SO with Collections.sort but I fail to implement it in my code.

NOTE: I do not have a datamodel defined for the AvailableFood object to populate the arrayList. Here is my code:

AvailableFood.java

public class AvailableFood extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        rootview = inflater.inflate(R.layout.fragment_available_food, container, false);

        mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                switch (menuItem.getItemId()){
                    case R.id.nav_sort:
                        PopupMenu popup = new PopupMenu(getContext(), rootview.findViewById(R.id.nav_sort));
                        MenuInflater inflater = popup.getMenuInflater();
                        inflater.inflate(R.menu.sort_menu, popup.getMenu());
                        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem menuItem) {
                                switch (menuItem.getItemId()){
                                    case R.id.sort_recent: sortAvailableFood("Time");
                                        break;
                                    case R.id.sort_qty: sortAvailableFood("Qty");
                                        break;
                                    case R.id.sort_rating: sortAvailableFood("Rating");
                                        break;
                                    case R.id.sort_distance: sortAvailableFood("Distance");
                                        break;
                                }
                                return true;
                            }
                        });
                        popup.show();

                }
                return false;
            }

        });
        lvAvlFood = rootview.findViewById(R.id.list_avl_food);

        arrListAvlFood = new ArrayList<HashMap<String, String >>();
        arrListLoc = new ArrayList<HashMap<String, String>>();

        return rootview;
    }

    private void sortAvailableFood(String by) {
        switch (by){
            case"Time":
                break;
            case"Qty":case"Qty":
                Collections.sort(arrListAvlFood, new Comparator<HashMap<String, String>>() {
                    @Override
                    public int compare(HashMap<String, String> obj1, HashMap<String, String> obj2) {
                        if( Double.parseDouble(obj1.get(AvailableFood.KEY_QTY)) > Double.parseDouble(obj2.get(AvailableFood.KEY_QTY)) ) {
                            return 1;
                        }
                        else {
                            return 0;
                        }
                    }
                });
                AvlFoodAdapter sortedAdapter = new AvlFoodAdapter(getActivity(),arrListAvlFood);
                lvAvlFood.setAdapter(sortedAdapter);

                break;
            case"Rating":
                break;
            case"Distance":
                break;
        }
    }
}

LoadAllFood.java

class LoadAllFood extends AsyncTask<String, String, String>{

    @Override
    protected String doInBackground(String... strings) {
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            String ngoId = new SessionManager(getContext()).getUserId();
            if(ngoId != null || !ngoId.equals("")) {
                params.add(new BasicNameValuePair("n_id", ngoId));
            }
            JSONObject json = jParser.makeHttpRequest(url_avl_food, "GET", params);

            try {
                int success = json.getInt("success");

                if (success == 1) {

                    jaAvlFood = json.getJSONArray("avl_food");

                    // looping through All Food
                    for (int i = 0; i < jaAvlFood.length(); i++) {
                        JSONObject c = jaAvlFood.getJSONObject(i);


                        String prep_time = c.getString("prep_time");
                        String upload_time = c.getString("upload_time");
                        Double qty = c.getDouble("qty");
                        resName = c.getString("res_name");
                        String lat = c.getString("lat");
                        String longi = c.getString("longi");
                        String rating = c.getString("g_rating");

                        HashMap<String, String> map = new HashMap<String, String>();
                        HashMap<String, String> hmLatLong = new HashMap<String, String>();

                        map.put("f_id", f_id);


                        map.put("prep_time",prep_time);
                        map.put("upload_time",upload_time);
                        map.put("qty",qty.toString());
                        map.put("name",resName);
                        map.put("g_rating", rating);


                        hmLatLong.put("lat",lat);
                        hmLatLong.put("longi",longi);

                        arrListAvlFood.add(map);
                        arrListLoc.add(hmLatLong);
                    }
                } else {

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
    }  
}
DIVYA RATHOD
  • 229
  • 3
  • 15
  • My suggestion is to use custom class for _Comparator_ and apply your logic there. And use your custom class for sorting. – Piyush Oct 01 '19 at 10:26
  • Why not just use recyclerview? – Kaushik Burkule Oct 01 '19 at 10:29
  • Can you tell what is wrong with this code? Why is this not working? I have also edited my code. – DIVYA RATHOD Oct 01 '19 at 11:13
  • You should use Model representation for your `AvailableFood` class. This will be much cleaner and easier to understand and you will also benefit from that implementation because then you will be able to sort the list according to `The time of food preparation` and other criteria, which will be the data member of your `AvailableFood` class. – ravi Oct 01 '19 at 11:23
  • @ravi Can you hint more about the Model class? Or can you resolve what's wrong with what I have done so far. I have debugged by application, the collections.sort method does not hit any breakpoint. – DIVYA RATHOD Oct 01 '19 at 11:29
  • @DIVYARATHOD Please look at my answer below and lets discuss there as to how you will benefit more from just using one POJO Class to model your data. – ravi Oct 01 '19 at 11:45

1 Answers1

1

Make a model class for Food which will enclose other data members and also make your code much readable.

 class Food {
    Integer foodId;
    String preparedAt;
    String uploadedAt;
    String name;
    // other data members

    //constructor


    //setter for food id
    public setFoodId(id){
        this.foodId = id
    }
    //getter for food id
    public getFoodId(){
        return this.foodId
    }


    //setters and getters for other data members

    //toString() method
}

Next up in your AsyncTask for LoadAllFoods you can do something like:

class LoadAllFood extends AsyncTask<Food, String, String>{
    @Override
    protected String doInBackground(Food... foods) {

    }
}

Now all you would need for your listview is a List<Food> and you can reference the value of preparedAt or any other data member on your adapter class doing something like: food.getFoodId();

ravi
  • 899
  • 8
  • 31