Display checkbox listview for filtering store selection

This commit is contained in:
Clayton Wilson 2020-11-01 02:42:02 -05:00
parent 33c3d8c56e
commit 9616c7a572
5 changed files with 162 additions and 48 deletions

View File

@ -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<String> selectedStores, double minPrice, double maxPrice);
}
public OnFilterListener onFilterListener;
CrystalRangeSeekbar priceSeekbar;
CheckBoxListViewAdapter checkBoxAdapter;
private int storeSelection;
private ArrayList<String> selectedStores;
private ArrayList<String> 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<String> stores, double maxProductPrice, double minPrice, double maxPrice) {
this.storeSelection = storeSelection;
public FilterDialogFragment(ArrayList<String> selectedStores, ArrayList<String> 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<String> 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<String> 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);

View File

@ -32,15 +32,15 @@ public class SearchResults extends AppCompatActivity implements FilterDialogFrag
private List<Product> resultsProductList = new ArrayList<>();
private List<Product> resultsProductListSorted = new ArrayList<>();
private ArrayList<String> stores = new ArrayList<>();
private int storeSelection;
private ArrayList<String> 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<String> 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<String>() {
@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<String>() {
@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<Product> 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);
}
});

View File

@ -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<String> list = new ArrayList<>();
ArrayList<String> checkedList = new ArrayList<>();
public CheckBoxListViewAdapter(Activity activity, ArrayList<String> list, ArrayList<String> 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<String> getChecked() {
return this.checkedList;
}
}

View File

@ -12,13 +12,10 @@
android:layout_marginStart="15dp"
android:text="@string/store_selection" />
<Spinner
android:id="@+id/sort_store_dropdown"
android:layout_width="265dp"
android:layout_marginStart="15dp"
android:layout_height="wrap_content"
android:background="@android:drawable/spinner_dropdown_background"
android:spinnerMode="dropdown"/>
<ListView
android:id="@+id/store_name_list"
android:layout_width="wrap_content"
android:layout_height="300dp"/>
<TextView
android:id="@+id/tv_price_label"

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/store_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginStart="30dp"/>
<CheckBox
android:id="@+id/store_check_box"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:focusable="false"
android:gravity="end"
android:layout_marginEnd="20dp"
android:layout_marginBottom="-5dp"
android:layout_alignParentEnd="true" />
</RelativeLayout>