From 9616c7a57294e4857484657e24a1881f23924b5e Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Sun, 1 Nov 2020 02:42:02 -0500 Subject: [PATCH] Display checkbox listview for filtering store selection --- .../example/listify/FilterDialogFragment.java | 43 ++++----- .../com/example/listify/SearchResults.java | 32 ++++--- .../adapter/CheckBoxListViewAdapter.java | 94 +++++++++++++++++++ .../app/src/main/res/layout/dialog_filter.xml | 11 +-- .../src/main/res/layout/filter_store_item.xml | 30 ++++++ 5 files changed, 162 insertions(+), 48 deletions(-) create mode 100644 Listify/app/src/main/java/com/example/listify/adapter/CheckBoxListViewAdapter.java create mode 100644 Listify/app/src/main/res/layout/filter_store_item.xml diff --git a/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java b/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java index fa2e9a1..e12eb39 100644 --- a/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java +++ b/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java @@ -6,36 +6,37 @@ 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.Spinner; +import android.widget.ListView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import com.crystal.crystalrangeseekbar.interfaces.OnRangeSeekbarChangeListener; import com.crystal.crystalrangeseekbar.widgets.CrystalRangeSeekbar; +import com.example.listify.adapter.CheckBoxListViewAdapter; + import java.util.ArrayList; public class FilterDialogFragment extends DialogFragment { public interface OnFilterListener { - void sendFilter(int storeSelection, double minPrice, double maxPrice); + void sendFilter(ArrayList selectedStores, double minPrice, double maxPrice); } public OnFilterListener onFilterListener; CrystalRangeSeekbar priceSeekbar; + CheckBoxListViewAdapter checkBoxAdapter; - private int storeSelection; + private ArrayList selectedStores; private ArrayList stores; private double maxProductPrice; // The highest price on the slider private double minPrice; // The selected min price private double maxPrice; // The selected max price - public FilterDialogFragment(int storeSelection, ArrayList stores, double maxProductPrice, double minPrice, double maxPrice) { - this.storeSelection = storeSelection; + public FilterDialogFragment(ArrayList selectedStores, ArrayList stores, double maxProductPrice, double minPrice, double maxPrice) { + this.selectedStores = selectedStores; this.stores = stores; this.maxProductPrice = maxProductPrice; this.minPrice = minPrice; @@ -57,7 +58,8 @@ public class FilterDialogFragment extends DialogFragment { .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { - onFilterListener.sendFilter(storeSelection, priceSeekbar.getSelectedMinValue().doubleValue(), priceSeekbar.getSelectedMaxValue().doubleValue()); + selectedStores = checkBoxAdapter.getChecked(); + onFilterListener.sendFilter(selectedStores, priceSeekbar.getSelectedMinValue().doubleValue(), priceSeekbar.getSelectedMaxValue().doubleValue()); } }) .setNegativeButton("cancel", new DialogInterface.OnClickListener() { @@ -66,28 +68,15 @@ public class FilterDialogFragment extends DialogFragment { } }); - 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); - } + ListView storesList = root.findViewById(R.id.store_name_list); - // Create the store selection dropdown - 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; - } + // Create arraylist of stores from search results + ArrayList storeChoices = new ArrayList<>(stores); - @Override - public void onNothingSelected(AdapterView parent) { + // Create adapter and send stores and selected stores + checkBoxAdapter = new CheckBoxListViewAdapter(getActivity(), storeChoices, this.selectedStores); - } - }); + storesList.setAdapter(checkBoxAdapter); // Set up the seekbar for price priceSeekbar = (CrystalRangeSeekbar) root.findViewById(R.id.price_range_seekbar); 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 7111156..80ddc3e 100644 --- a/Listify/app/src/main/java/com/example/listify/SearchResults.java +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -32,15 +32,15 @@ public class SearchResults extends AppCompatActivity implements FilterDialogFrag private List resultsProductList = new ArrayList<>(); private List resultsProductListSorted = new ArrayList<>(); private ArrayList stores = new ArrayList<>(); - private int storeSelection; + private ArrayList selectedStores = new ArrayList<>(); private SortModes sortMode = SortModes.NONE; private boolean descending; private double minPrice = 0; private double maxPrice = -1; @Override - public void sendFilter(int storeSelection, double minPrice, double maxPrice) { - this.storeSelection = storeSelection; + public void sendFilter(ArrayList selectedStores, double minPrice, double maxPrice) { + this.selectedStores = selectedStores; this.minPrice = minPrice; this.maxPrice = maxPrice; sortResults(); @@ -138,14 +138,6 @@ public class SearchResults extends AppCompatActivity implements FilterDialogFrag filterItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - // Sort the store list - stores.sort(new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1.compareTo(o2); - } - }); - // Determine the max price for the price slider double maxProductPrice; if (resultsProductList.isEmpty()) { @@ -169,7 +161,7 @@ public class SearchResults extends AppCompatActivity implements FilterDialogFrag // Round up to nearest whole number for display on price seekbar maxProductPrice = Math.ceil(maxProductPrice); - FilterDialogFragment sortDialog = new FilterDialogFragment(storeSelection, stores, maxProductPrice, minPrice, maxPrice); + FilterDialogFragment sortDialog = new FilterDialogFragment(selectedStores, stores, maxProductPrice, minPrice, maxPrice); sortDialog.show(getSupportFragmentManager(), "Filter Dialog"); return false; } @@ -227,6 +219,18 @@ public class SearchResults extends AppCompatActivity implements FilterDialogFrag } } + // Sort the store list + stores.sort(new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }); + + // Reset selected stores on search so that every store is selected + this.selectedStores.clear(); + this.selectedStores.addAll(stores); + // Add all results to the sorted list resultsProductListSorted.addAll(resultsProductList); @@ -311,10 +315,10 @@ public class SearchResults extends AppCompatActivity implements FilterDialogFrag } // Only keep results that match the current store selection - if (this.storeSelection != 0) { + if (!this.selectedStores.equals(this.stores)) { ArrayList temp = new ArrayList<>(); resultsProductListSorted.forEach(product -> { - if (product.getChainName().equals(this.stores.get(this.storeSelection - 1))) { + if (this.selectedStores.contains(product.getChainName())) { temp.add(product); } }); diff --git a/Listify/app/src/main/java/com/example/listify/adapter/CheckBoxListViewAdapter.java b/Listify/app/src/main/java/com/example/listify/adapter/CheckBoxListViewAdapter.java new file mode 100644 index 0000000..5951d79 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/adapter/CheckBoxListViewAdapter.java @@ -0,0 +1,94 @@ +package com.example.listify.adapter; +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.TextView; +import com.example.listify.R; + +import java.util.ArrayList; + +public class CheckBoxListViewAdapter extends BaseAdapter { + private Activity activity; + ArrayList list = new ArrayList<>(); + ArrayList checkedList = new ArrayList<>(); + + public CheckBoxListViewAdapter(Activity activity, ArrayList list, ArrayList checkedList) { + super(); + this.activity = activity; + this.list = list; + this.checkedList = checkedList; + } + + @Override + public int getCount() { + return list.size(); + } + + @Override + public String getItem(int position) { + return list.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + public class ViewHolder { + public TextView label; + public CheckBox checkBox; + } + @Override + public View getView(final int position, View convertView, ViewGroup parent) { + ViewHolder holder; + LayoutInflater inflator = ((Activity) activity).getLayoutInflater(); + + if (convertView == null) { + convertView = inflator.inflate(R.layout.filter_store_item, null); + + convertView.setSoundEffectsEnabled(false); + + holder = new ViewHolder(); + holder.label = (TextView) convertView.findViewById(R.id.store_name); + holder.checkBox = (CheckBox)convertView.findViewById(R.id.store_check_box); + + holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + int getPosition = (Integer) buttonView.getTag(); + + if (isChecked) { + checkedList.add(list.get(getPosition)); + } else { + checkedList.remove(list.get(getPosition)); + } + } + }); + + convertView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + System.out.println("clicked"); + holder.checkBox.performClick(); + } + }); + + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + holder.checkBox.setTag(position); + holder.label.setText("" + list.get(position)); + holder.checkBox.setChecked(checkedList.contains(list.get(position))); + return convertView; + } + + public ArrayList getChecked() { + return this.checkedList; + } +} diff --git a/Listify/app/src/main/res/layout/dialog_filter.xml b/Listify/app/src/main/res/layout/dialog_filter.xml index 4783b06..03ec65c 100644 --- a/Listify/app/src/main/res/layout/dialog_filter.xml +++ b/Listify/app/src/main/res/layout/dialog_filter.xml @@ -12,13 +12,10 @@ android:layout_marginStart="15dp" android:text="@string/store_selection" /> - + + + + + + + + \ No newline at end of file