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/SearchResults.java b/Listify/app/src/main/java/com/example/listify/SearchResults.java index 602b752..0421b58 100644 --- a/Listify/app/src/main/java/com/example/listify/SearchResults.java +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -32,12 +32,16 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme private int storeSelection; private int sortMode; private boolean descending; + private double minPrice = 0; + private double maxPrice = -1; @Override - public void sendSort(int storeSelection, int sortMode, boolean descending) { + 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; sortResults(); } @@ -86,7 +90,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 @@ -118,6 +121,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() { @@ -130,7 +135,31 @@ 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 == -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"); } }); @@ -217,6 +246,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); @@ -236,6 +266,24 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme resultsProductListSorted.clear(); 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); + + runOnUiThread(new Runnable() { + @Override + public void run() { + searchResultsListAdapter.notifyDataSetChanged(); + } + }); } // This is called after the search results come back from the server @@ -243,7 +291,6 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme @Override public void acceptDelivery(Object delivered) { ItemSearch results = (ItemSearch) delivered; - try { for (int i = 0; i < results.getResults().size(); i++) { // TODO: Change to dynamically grab chain name by id @@ -281,8 +328,6 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme runOnUiThread(new Runnable() { @Override public void run() { - searchResultsListAdapter.notifyDataSetChanged(); - // Hide progress bar loadingSearch.setVisibility(View.GONE); 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..7cc71a4 100644 --- a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java +++ b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java @@ -10,30 +10,44 @@ 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.widgets.CrystalRangeSeekbar; + 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; } @@ -51,7 +65,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() { @@ -91,7 +105,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) { @@ -125,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 @@ -136,6 +148,25 @@ public class SortDialogFragment extends DialogFragment { sortDirectionButton.setEnabled(false); } + // Set up the seekbar for price + 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((float) this.maxProductPrice); + priceSeekbar.setMinStartValue((float) this.minPrice); + priceSeekbar.setMaxStartValue((float) this.maxPrice); + priceSeekbar.apply(); + + // 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())); + } + }); + 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