From 550483a70876180a5176738719d97ba2f3f8b7ea Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Tue, 29 Sep 2020 12:53:31 -0400 Subject: [PATCH] Dialog for sorting search results --- .../com/example/listify/SearchResults.java | 107 +++++++++++---- .../example/listify/SortDialogFragment.java | 124 ++++++++++++++++++ .../ic_baseline_arrow_drop_down_24.xml | 10 ++ .../drawable/ic_baseline_filter_list_28.xml | 10 ++ .../res/drawable/ic_baseline_search_28.xml | 10 ++ .../main/res/drawable/ic_baseline_sort_28.xml | 5 + .../res/layout/activity_search_results.xml | 9 +- .../app/src/main/res/layout/app_bar_home.xml | 2 +- .../app/src/main/res/layout/dialog_sort.xml | 61 +++++++++ Listify/app/src/main/res/menu/main.xml | 5 - Listify/app/src/main/res/values/strings.xml | 1 + 11 files changed, 310 insertions(+), 34 deletions(-) create mode 100644 Listify/app/src/main/java/com/example/listify/SortDialogFragment.java create mode 100644 Listify/app/src/main/res/drawable/ic_baseline_arrow_drop_down_24.xml create mode 100644 Listify/app/src/main/res/drawable/ic_baseline_filter_list_28.xml create mode 100644 Listify/app/src/main/res/drawable/ic_baseline_search_28.xml create mode 100644 Listify/app/src/main/res/drawable/ic_baseline_sort_28.xml create mode 100644 Listify/app/src/main/res/layout/dialog_sort.xml diff --git a/Listify/app/src/main/java/com/example/listify/SearchResults.java b/Listify/app/src/main/java/com/example/listify/SearchResults.java index 6265894..b5d0c2e 100644 --- a/Listify/app/src/main/java/com/example/listify/SearchResults.java +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -10,20 +10,29 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.SearchView; import android.widget.Toast; - import com.example.listify.adapter.SearchResultsListAdapter; import com.example.listify.model.Product; - import java.util.ArrayList; import java.util.Comparator; import java.util.List; -public class SearchResults extends AppCompatActivity { +public class SearchResults extends AppCompatActivity implements SortDialogFragment.OnSortingListener { private ListView listView; private SearchResultsListAdapter searchResultsListAdapter; private List resultsProductList = new ArrayList<>(); - private List resultsProductListFiltered = new ArrayList<>(); + private List resultsProductListSorted = new ArrayList<>(); + private ArrayList stores = new ArrayList<>(); + private int storeSelection; + private int sortMode; + private boolean descending; + @Override + public void sendSort(int storeSelection, int sortMode, boolean descending) { + this.storeSelection = storeSelection; + this.sortMode = sortMode; + this.descending = descending; + sortResults(); + } @Override protected void onCreate(Bundle savedInstanceState) { @@ -63,12 +72,12 @@ public class SearchResults extends AppCompatActivity { }); listView = (ListView) findViewById(R.id.search_results_list); - searchResultsListAdapter = new SearchResultsListAdapter(this, resultsProductListFiltered); + searchResultsListAdapter = new SearchResultsListAdapter(this, resultsProductListSorted); listView.setAdapter(searchResultsListAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - Toast.makeText(SearchResults.this, resultsProductListFiltered.get(position).getItemName(), Toast.LENGTH_SHORT).show(); + Toast.makeText(SearchResults.this, resultsProductListSorted.get(position).getItemName(), Toast.LENGTH_SHORT).show(); } }); @@ -86,8 +95,28 @@ public class SearchResults extends AppCompatActivity { } }); + // Create a dialog for filtering and sorting search results + ImageButton sortButton = (ImageButton) findViewById(R.id.results_sort_button); + sortButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Sort the store list + stores.sort(new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }); + SortDialogFragment sortDialog = new SortDialogFragment(storeSelection, stores, sortMode, descending); + sortDialog.show(getSupportFragmentManager(), "Sort"); + } + }); + } + + + // Override default phone back button to add animation @Override public void onBackPressed() { @@ -116,22 +145,38 @@ public class SearchResults extends AppCompatActivity { resultsProductList.add(f); } - // Add all results to the filtered list - resultsProductListFiltered.addAll(resultsProductList); + // Create a list of all stores in the results so the user can filter by store name + for (int i = 0; i < resultsProductList.size(); i++) { + if (!stores.contains(resultsProductList.get(i).getChainName())) { + stores.add(resultsProductList.get(i).getChainName()); + } + } + + // Add all results to the sorted list + resultsProductListSorted.addAll(resultsProductList); + + // Apply selected sorting to the list + sortResults(); } // Sorts the search results - private void sortResults(int sortMode, boolean descending) { + private void sortResults() { // Sort Modes - // 0 itemName - // 1 price - // 2 chainName - // 3 upc + // 0 default (no sorting) + // 1 itemName + // 2 price + // 3 chainName + // 4 upc // Sort based on mode - switch (sortMode) { + switch (this.sortMode) { case 0: - resultsProductListFiltered.sort(new Comparator() { + resultsProductListSorted.clear(); + resultsProductListSorted.addAll(resultsProductList); + searchResultsListAdapter.notifyDataSetChanged(); + return; + case 1: + resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { return a.getItemName().compareToIgnoreCase(b.getItemName()); @@ -140,17 +185,23 @@ public class SearchResults extends AppCompatActivity { break; // TODO: May need to change this depending on if price is stored as a string or a double - case 1: - resultsProductListFiltered.sort(new Comparator() { + case 2: + resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { - return (int)(a.getPrice() - b.getPrice()); + if (a.getPrice() - b.getPrice() > 0) { + return 1; + } else if (a.getPrice() - b.getPrice() < 0) { + return -1; + } else { + return 0; + } } }); break; - case 2: - resultsProductListFiltered.sort(new Comparator() { + case 3: + resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { return a.getChainName().compareToIgnoreCase(b.getChainName()); @@ -158,8 +209,8 @@ public class SearchResults extends AppCompatActivity { }); break; - case 3: - resultsProductListFiltered.sort(new Comparator() { + case 4: + resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { return a.getUpc().compareToIgnoreCase(b.getUpc()); @@ -168,12 +219,14 @@ public class SearchResults extends AppCompatActivity { break; } - if (descending) { - for (int i = 0; i < resultsProductListFiltered.size() / 2; i++) { - Product temp = resultsProductListFiltered.get(i); - resultsProductListFiltered.set(i, resultsProductListFiltered.get(resultsProductListFiltered.size() - i - 1)); - resultsProductListFiltered.set(resultsProductListFiltered.size() - i - 1, temp); + if (this.descending) { + for (int i = 0; i < resultsProductListSorted.size() / 2; i++) { + Product temp = resultsProductListSorted.get(i); + resultsProductListSorted.set(i, resultsProductListSorted.get(resultsProductListSorted.size() - i - 1)); + resultsProductListSorted.set(resultsProductListSorted.size() - i - 1, temp); } } + + searchResultsListAdapter.notifyDataSetChanged(); } } \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java new file mode 100644 index 0000000..3a9816f --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java @@ -0,0 +1,124 @@ +package com.example.listify; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageButton; +import android.widget.Spinner; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; +import java.util.ArrayList; + + +public class SortDialogFragment extends DialogFragment { + + public interface OnSortingListener { + void sendSort(int storeSelection, int sortMode, boolean descending); + } + + public OnSortingListener onSortingListener; + + private int storeSelection; + private int sortMode; + private boolean descending; + private ArrayList stores; + + public SortDialogFragment(int storeSelection, ArrayList stores, int sortMode, boolean descending) { + this.storeSelection = storeSelection; + this.stores = stores; + this.sortMode = sortMode; + this.descending = descending; + } + + @Override + public Dialog onCreateDialog(final Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Get the layout inflater + LayoutInflater inflater = requireActivity().getLayoutInflater(); + + // Inflate and set the layout for the dialog + // Pass null as the parent view because its going in the dialog layout + View root = inflater.inflate(R.layout.dialog_sort, null); + builder.setView(root) + // Add action buttons + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + onSortingListener.sendSort(storeSelection, sortMode, descending); + } + }) + .setNegativeButton("cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + SortDialogFragment.this.getDialog().cancel(); + } + }); + + Spinner storeDropdown = (Spinner) root.findViewById(R.id.sort_store_dropdown); + String[] storeChoices = new String[stores.size() + 1]; + storeChoices[0] = "All"; + for (int i = 1; i < stores.size() + 1; i++) { + storeChoices[i] = stores.get(i - 1); + } + ArrayAdapter storeAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_dropdown_item, storeChoices); + storeDropdown.setAdapter(storeAdapter); + storeDropdown.setSelection(this.storeSelection); + storeDropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + storeSelection = position; + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + + Spinner sortDropdown = (Spinner) root.findViewById(R.id.sort_mode_dropdown); + String[] items = new String[] {"", "Name", "Price", "Store"}; + ArrayAdapter adapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_dropdown_item, items); + sortDropdown.setAdapter(adapter); + sortDropdown.setSelection(this.sortMode); + sortDropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + sortMode = position; + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + + ImageButton sortDirectionButton = root.findViewById(R.id.sort_direction_button); + sortDirectionButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (descending) { + descending = false; + } else { + descending = true; + } + } + }); + + return builder.create(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + try { + onSortingListener = (OnSortingListener) getActivity(); + } catch (ClassCastException e) { + Log.e("SortDialogFragment", "onAttach: ClassCastException: " + e.getMessage()); + } + } +} diff --git a/Listify/app/src/main/res/drawable/ic_baseline_arrow_drop_down_24.xml b/Listify/app/src/main/res/drawable/ic_baseline_arrow_drop_down_24.xml new file mode 100644 index 0000000..ce58346 --- /dev/null +++ b/Listify/app/src/main/res/drawable/ic_baseline_arrow_drop_down_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/Listify/app/src/main/res/drawable/ic_baseline_filter_list_28.xml b/Listify/app/src/main/res/drawable/ic_baseline_filter_list_28.xml new file mode 100644 index 0000000..4ecf051 --- /dev/null +++ b/Listify/app/src/main/res/drawable/ic_baseline_filter_list_28.xml @@ -0,0 +1,10 @@ + + + diff --git a/Listify/app/src/main/res/drawable/ic_baseline_search_28.xml b/Listify/app/src/main/res/drawable/ic_baseline_search_28.xml new file mode 100644 index 0000000..d14c485 --- /dev/null +++ b/Listify/app/src/main/res/drawable/ic_baseline_search_28.xml @@ -0,0 +1,10 @@ + + + diff --git a/Listify/app/src/main/res/drawable/ic_baseline_sort_28.xml b/Listify/app/src/main/res/drawable/ic_baseline_sort_28.xml new file mode 100644 index 0000000..60dff03 --- /dev/null +++ b/Listify/app/src/main/res/drawable/ic_baseline_sort_28.xml @@ -0,0 +1,5 @@ + + + diff --git a/Listify/app/src/main/res/layout/activity_search_results.xml b/Listify/app/src/main/res/layout/activity_search_results.xml index 457d2e1..2d8356e 100644 --- a/Listify/app/src/main/res/layout/activity_search_results.xml +++ b/Listify/app/src/main/res/layout/activity_search_results.xml @@ -36,10 +36,17 @@ > + - \ + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/app_bar_home.xml b/Listify/app/src/main/res/layout/app_bar_home.xml index 41992e1..285fb12 100644 --- a/Listify/app/src/main/res/layout/app_bar_home.xml +++ b/Listify/app/src/main/res/layout/app_bar_home.xml @@ -23,7 +23,7 @@ android:layout_gravity="end" android:layout_marginEnd="5dp" android:layout_height="wrap_content" - app:srcCompat="@android:drawable/ic_menu_search" + app:srcCompat="@drawable/ic_baseline_search_28" android:contentDescription="@string/search_button_desc" android:background="@null"/> diff --git a/Listify/app/src/main/res/layout/dialog_sort.xml b/Listify/app/src/main/res/layout/dialog_sort.xml new file mode 100644 index 0000000..408d835 --- /dev/null +++ b/Listify/app/src/main/res/layout/dialog_sort.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/menu/main.xml b/Listify/app/src/main/res/menu/main.xml index 86282df..8730faa 100644 --- a/Listify/app/src/main/res/menu/main.xml +++ b/Listify/app/src/main/res/menu/main.xml @@ -6,9 +6,4 @@ android:orderInCategory="101" android:title="@string/action_settings" app:showAsAction="never" /> - diff --git a/Listify/app/src/main/res/values/strings.xml b/Listify/app/src/main/res/values/strings.xml index a969f55..00ee306 100644 --- a/Listify/app/src/main/res/values/strings.xml +++ b/Listify/app/src/main/res/values/strings.xml @@ -15,6 +15,7 @@ Search Test SearchActivity Product Image + Sort Icon First Fragment