From e98d2a6a937f132462d35216b9fd7f1e151651f1 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Sun, 18 Oct 2020 19:50:00 -0400 Subject: [PATCH 1/3] Search activity price seekbar layout --- Listify/app/build.gradle | 2 +- .../example/listify/SortDialogFragment.java | 34 +++++++++++++++ .../app/src/main/res/layout/dialog_sort.xml | 43 ++++++++++++++++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/Listify/app/build.gradle b/Listify/app/build.gradle index 0ad5dc3..d90a79b 100644 --- a/Listify/app/build.gradle +++ b/Listify/app/build.gradle @@ -51,5 +51,5 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' implementation 'com.squareup.okhttp3:okhttp:4.8.1' - + implementation 'com.crystal:crystalrangeseekbar:1.1.3' } \ 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 index ac4713f..d94f120 100644 --- a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java +++ b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java @@ -10,9 +10,18 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageButton; import android.widget.Spinner; +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.interfaces.OnRangeSeekbarFinalValueListener; +import com.crystal.crystalrangeseekbar.widgets.CrystalRangeSeekbar; + +import org.w3c.dom.Text; + import java.util.ArrayList; @@ -136,6 +145,31 @@ public class SortDialogFragment extends DialogFragment { sortDirectionButton.setEnabled(false); } + // Set up the seekbar for price + final CrystalRangeSeekbar priceSeekbar = (CrystalRangeSeekbar) root.findViewById(R.id.price_range_seekbar); + final TextView tvMin = (TextView) root.findViewById(R.id.tv_min_price); + final TextView tvMax = (TextView) root.findViewById(R.id.tv_max_price); + + priceSeekbar.setMaxValue(367); + + // Update price display + priceSeekbar.setOnRangeSeekbarChangeListener(new OnRangeSeekbarChangeListener() { + @Override + public void valueChanged(Number minValue, Number maxValue) { + tvMin.setText(String.format("$%.2f", minValue.doubleValue())); + tvMax.setText(String.format("$%.2f", maxValue.doubleValue())); + } + }); + + // Save price values when user finishes moving the slider + priceSeekbar.setOnRangeSeekbarFinalValueListener(new OnRangeSeekbarFinalValueListener() { + @Override + public void finalValue(Number minValue, Number maxValue) { + System.out.println(String.format("Min: $%.2f, Max: $%.2f", minValue.doubleValue(), maxValue.doubleValue())); + } + }); + + return builder.create(); } diff --git a/Listify/app/src/main/res/layout/dialog_sort.xml b/Listify/app/src/main/res/layout/dialog_sort.xml index 38e5002..6a6d5b1 100644 --- a/Listify/app/src/main/res/layout/dialog_sort.xml +++ b/Listify/app/src/main/res/layout/dialog_sort.xml @@ -31,7 +31,7 @@ + + + + + + + + + + + + + \ No newline at end of file From c9d40d0eaec6699c4e817a18e4b345596463d3c2 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Sat, 24 Oct 2020 13:51:11 -0400 Subject: [PATCH 2/3] Price filter debugging --- .../com/example/listify/SearchResults.java | 30 ++++++++++++- .../example/listify/SortDialogFragment.java | 42 ++++++++++++------- 2 files changed, 55 insertions(+), 17 deletions(-) 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 0b312c6..429c080 100644 --- a/Listify/app/src/main/java/com/example/listify/SearchResults.java +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -31,12 +31,18 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme private int storeSelection; private int sortMode; private boolean descending; + private double minPrice = 0; + private double maxPrice = 0; @Override - public void sendSort(int storeSelection, int sortMode, boolean descending) { + public void sendSort(int storeSelection, int sortMode, boolean descending, double maxPrice, double minPrice) { this.storeSelection = storeSelection; this.sortMode = sortMode; this.descending = descending; + this.minPrice = minPrice; + this.maxPrice = maxPrice; + System.out.println(minPrice); + System.out.println(maxPrice); sortResults(); } @@ -118,7 +124,27 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme return o1.compareTo(o2); } }); - SortDialogFragment sortDialog = new SortDialogFragment(storeSelection, stores, sortMode, descending); + + // Determine the max price for the price slider + double maxProductPrice; + if (resultsProductList.isEmpty()) { + // default to $100 + maxProductPrice = 100.00; + + minPrice = 0; + maxPrice = 100; + } else { + maxProductPrice = resultsProductList.get(0).getPrice().doubleValue(); + for (int i = 1; i < resultsProductList.size(); i++) { + if (resultsProductList.get(i).getPrice().doubleValue() > maxProductPrice) { + maxProductPrice = resultsProductList.get(i).getPrice().doubleValue(); + } + } + if (maxPrice == 0) { + maxPrice = maxProductPrice; + } + } + SortDialogFragment sortDialog = new SortDialogFragment(storeSelection, stores, sortMode, descending, maxProductPrice, minPrice, maxPrice); sortDialog.show(getSupportFragmentManager(), "Sort"); } }); diff --git a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java index d94f120..c5862ef 100644 --- a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java +++ b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java @@ -20,29 +20,35 @@ import com.crystal.crystalrangeseekbar.interfaces.OnRangeSeekbarChangeListener; import com.crystal.crystalrangeseekbar.interfaces.OnRangeSeekbarFinalValueListener; import com.crystal.crystalrangeseekbar.widgets.CrystalRangeSeekbar; -import org.w3c.dom.Text; - import java.util.ArrayList; public class SortDialogFragment extends DialogFragment { public interface OnSortingListener { - void sendSort(int storeSelection, int sortMode, boolean descending); + void sendSort(int storeSelection, int sortMode, boolean descending, double minPrice, double maxPrice); } public OnSortingListener onSortingListener; + CrystalRangeSeekbar priceSeekbar; + private int storeSelection; private int sortMode; private boolean descending; 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 SortDialogFragment(int storeSelection, ArrayList stores, int sortMode, boolean descending) { + public SortDialogFragment(int storeSelection, ArrayList stores, int sortMode, boolean descending, double maxProductPrice, double minPrice, double maxPrice) { this.storeSelection = storeSelection; this.stores = stores; this.sortMode = sortMode; this.descending = descending; + this.maxProductPrice = maxProductPrice; + this.minPrice = minPrice; + this.maxPrice = maxPrice; } @@ -60,7 +66,7 @@ public class SortDialogFragment extends DialogFragment { .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { - onSortingListener.sendSort(storeSelection, sortMode, descending); + onSortingListener.sendSort(storeSelection, sortMode, descending, priceSeekbar.getSelectedMinValue().doubleValue(), priceSeekbar.getSelectedMaxValue().doubleValue()); } }) .setNegativeButton("cancel", new DialogInterface.OnClickListener() { @@ -100,7 +106,7 @@ public class SortDialogFragment extends DialogFragment { sortDirectionButton.setImageResource(R.drawable.ic_baseline_arrow_upward_50); } - // Change array pointing direction whenever the user clicks the button + // Change arrow pointing direction whenever the user clicks the button sortDirectionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -146,11 +152,15 @@ public class SortDialogFragment extends DialogFragment { } // Set up the seekbar for price - final CrystalRangeSeekbar priceSeekbar = (CrystalRangeSeekbar) root.findViewById(R.id.price_range_seekbar); + priceSeekbar = (CrystalRangeSeekbar) root.findViewById(R.id.price_range_seekbar); final TextView tvMin = (TextView) root.findViewById(R.id.tv_min_price); final TextView tvMax = (TextView) root.findViewById(R.id.tv_max_price); - priceSeekbar.setMaxValue(367); + priceSeekbar.setMaxValue((float) this.maxProductPrice); + System.out.println(String.format("%f : %f", this.minPrice, this.maxPrice)); + priceSeekbar.setMinStartValue((float) this.minPrice); + priceSeekbar.setMaxStartValue((float) this.maxPrice); + priceSeekbar.apply(); // Update price display priceSeekbar.setOnRangeSeekbarChangeListener(new OnRangeSeekbarChangeListener() { @@ -161,13 +171,15 @@ public class SortDialogFragment extends DialogFragment { } }); - // Save price values when user finishes moving the slider - priceSeekbar.setOnRangeSeekbarFinalValueListener(new OnRangeSeekbarFinalValueListener() { - @Override - public void finalValue(Number minValue, Number maxValue) { - System.out.println(String.format("Min: $%.2f, Max: $%.2f", minValue.doubleValue(), maxValue.doubleValue())); - } - }); +// // Save price values when user finishes moving the slider +// priceSeekbar.setOnRangeSeekbarFinalValueListener(new OnRangeSeekbarFinalValueListener() { +// @Override +// public void finalValue(Number minValue, Number maxValue) { +// minPrice = minValue.doubleValue(); +// maxPrice = maxValue.doubleValue(); +//// System.out.println(String.format("Min: $%.2f, Max: $%.2f", minValue.doubleValue(), maxValue.doubleValue())); +// } +// }); return builder.create(); From 9462bc67239b5403dc883398f5594c0022097df2 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Sun, 25 Oct 2020 21:19:02 -0400 Subject: [PATCH 3/3] Price range filtering finished --- .../com/example/listify/SearchResults.java | 27 ++++++++++++++----- .../example/listify/SortDialogFragment.java | 17 +----------- 2 files changed, 22 insertions(+), 22 deletions(-) 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 429c080..fcea894 100644 --- a/Listify/app/src/main/java/com/example/listify/SearchResults.java +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -32,17 +32,15 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme private int sortMode; private boolean descending; private double minPrice = 0; - private double maxPrice = 0; + private double maxPrice = -1; @Override - public void sendSort(int storeSelection, int sortMode, boolean descending, double maxPrice, double minPrice) { + public void sendSort(int storeSelection, int sortMode, boolean descending, double minPrice, double maxPrice) { this.storeSelection = storeSelection; this.sortMode = sortMode; this.descending = descending; this.minPrice = minPrice; this.maxPrice = maxPrice; - System.out.println(minPrice); - System.out.println(maxPrice); sortResults(); } @@ -89,7 +87,6 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { -// Toast.makeText(SearchResults.this, resultsProductListSorted.get(position).getItemName(), Toast.LENGTH_SHORT).show(); Intent itemDetailsPage = new Intent(SearchResults.this, ItemDetails.class); // Send the selected product @@ -112,6 +109,8 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme } }); + // TODO: Change this to a menu in which sort and filter are two different options + // TODO: Sort should be disabled until a search is made // Create a dialog for filtering and sorting search results ImageButton sortButton = (ImageButton) findViewById(R.id.results_sort_button); sortButton.setOnClickListener(new View.OnClickListener() { @@ -140,10 +139,14 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme maxProductPrice = resultsProductList.get(i).getPrice().doubleValue(); } } - if (maxPrice == 0) { + if (maxPrice == -1) { maxPrice = maxProductPrice; } } + + // Round up to nearest whole number for display on price seekbar + maxProductPrice = Math.ceil(maxProductPrice); + SortDialogFragment sortDialog = new SortDialogFragment(storeSelection, stores, sortMode, descending, maxProductPrice, minPrice, maxPrice); sortDialog.show(getSupportFragmentManager(), "Sort"); } @@ -264,6 +267,7 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme break; } + // Flip the list if descending is selected if (this.sortMode != 0 & this.descending) { for (int i = 0; i < resultsProductListSorted.size() / 2; i++) { Product temp = resultsProductListSorted.get(i); @@ -284,6 +288,17 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme resultsProductListSorted.addAll(temp); } + // Filter out products that don't fit price restraints + ArrayList temp = new ArrayList<>(); + resultsProductListSorted.forEach(product -> { + if (product.getPrice().doubleValue() >= this.minPrice && + (this.maxPrice == -1 || product.getPrice().doubleValue() <= this.maxPrice)) { + temp.add(product); + } + }); + resultsProductListSorted.clear(); + resultsProductListSorted.addAll(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 index c5862ef..7cc71a4 100644 --- a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java +++ b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java @@ -17,7 +17,6 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import com.crystal.crystalrangeseekbar.interfaces.OnRangeSeekbarChangeListener; -import com.crystal.crystalrangeseekbar.interfaces.OnRangeSeekbarFinalValueListener; import com.crystal.crystalrangeseekbar.widgets.CrystalRangeSeekbar; import java.util.ArrayList; @@ -140,9 +139,7 @@ public class SortDialogFragment extends DialogFragment { } @Override - public void onNothingSelected(AdapterView parent) { - - } + public void onNothingSelected(AdapterView parent) {} }); // Disable the direction button if they have the default sorting mode selected @@ -157,7 +154,6 @@ public class SortDialogFragment extends DialogFragment { final TextView tvMax = (TextView) root.findViewById(R.id.tv_max_price); priceSeekbar.setMaxValue((float) this.maxProductPrice); - System.out.println(String.format("%f : %f", this.minPrice, this.maxPrice)); priceSeekbar.setMinStartValue((float) this.minPrice); priceSeekbar.setMaxStartValue((float) this.maxPrice); priceSeekbar.apply(); @@ -171,17 +167,6 @@ public class SortDialogFragment extends DialogFragment { } }); -// // Save price values when user finishes moving the slider -// priceSeekbar.setOnRangeSeekbarFinalValueListener(new OnRangeSeekbarFinalValueListener() { -// @Override -// public void finalValue(Number minValue, Number maxValue) { -// minPrice = minValue.doubleValue(); -// maxPrice = maxValue.doubleValue(); -//// System.out.println(String.format("Min: $%.2f, Max: $%.2f", minValue.doubleValue(), maxValue.doubleValue())); -// } -// }); - - return builder.create(); }