mirror of
https://github.com/ClaytonWWilson/Listify.git
synced 2025-12-16 18:48:48 +00:00
commit
52e76be34a
@ -51,5 +51,5 @@ dependencies {
|
|||||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.8.1'
|
implementation 'com.squareup.okhttp3:okhttp:4.8.1'
|
||||||
|
implementation 'com.crystal:crystalrangeseekbar:1.1.3'
|
||||||
}
|
}
|
||||||
@ -32,12 +32,16 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
private int storeSelection;
|
private int storeSelection;
|
||||||
private int sortMode;
|
private int sortMode;
|
||||||
private boolean descending;
|
private boolean descending;
|
||||||
|
private double minPrice = 0;
|
||||||
|
private double maxPrice = -1;
|
||||||
|
|
||||||
@Override
|
@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.storeSelection = storeSelection;
|
||||||
this.sortMode = sortMode;
|
this.sortMode = sortMode;
|
||||||
this.descending = descending;
|
this.descending = descending;
|
||||||
|
this.minPrice = minPrice;
|
||||||
|
this.maxPrice = maxPrice;
|
||||||
sortResults();
|
sortResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +90,6 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
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);
|
Intent itemDetailsPage = new Intent(SearchResults.this, ItemDetails.class);
|
||||||
|
|
||||||
// Send the selected product
|
// 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
|
// Create a dialog for filtering and sorting search results
|
||||||
ImageButton sortButton = (ImageButton) findViewById(R.id.results_sort_button);
|
ImageButton sortButton = (ImageButton) findViewById(R.id.results_sort_button);
|
||||||
sortButton.setOnClickListener(new View.OnClickListener() {
|
sortButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@ -130,7 +135,31 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
return o1.compareTo(o2);
|
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");
|
sortDialog.show(getSupportFragmentManager(), "Sort");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -217,6 +246,7 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flip the list if descending is selected
|
||||||
if (this.sortMode != 0 & this.descending) {
|
if (this.sortMode != 0 & this.descending) {
|
||||||
for (int i = 0; i < resultsProductListSorted.size() / 2; i++) {
|
for (int i = 0; i < resultsProductListSorted.size() / 2; i++) {
|
||||||
Product temp = resultsProductListSorted.get(i);
|
Product temp = resultsProductListSorted.get(i);
|
||||||
@ -236,6 +266,24 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
resultsProductListSorted.clear();
|
resultsProductListSorted.clear();
|
||||||
resultsProductListSorted.addAll(temp);
|
resultsProductListSorted.addAll(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter out products that don't fit price restraints
|
||||||
|
ArrayList<Product> 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
|
// This is called after the search results come back from the server
|
||||||
@ -243,7 +291,6 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
@Override
|
@Override
|
||||||
public void acceptDelivery(Object delivered) {
|
public void acceptDelivery(Object delivered) {
|
||||||
ItemSearch results = (ItemSearch) delivered;
|
ItemSearch results = (ItemSearch) delivered;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < results.getResults().size(); i++) {
|
for (int i = 0; i < results.getResults().size(); i++) {
|
||||||
// TODO: Change to dynamically grab chain name by id
|
// TODO: Change to dynamically grab chain name by id
|
||||||
@ -281,8 +328,6 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
|
|||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
searchResultsListAdapter.notifyDataSetChanged();
|
|
||||||
|
|
||||||
// Hide progress bar
|
// Hide progress bar
|
||||||
loadingSearch.setVisibility(View.GONE);
|
loadingSearch.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
|||||||
@ -10,30 +10,44 @@ import android.widget.AdapterView;
|
|||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
|
import com.crystal.crystalrangeseekbar.interfaces.OnRangeSeekbarChangeListener;
|
||||||
|
import com.crystal.crystalrangeseekbar.widgets.CrystalRangeSeekbar;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
public class SortDialogFragment extends DialogFragment {
|
public class SortDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
public interface OnSortingListener {
|
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;
|
public OnSortingListener onSortingListener;
|
||||||
|
|
||||||
|
CrystalRangeSeekbar priceSeekbar;
|
||||||
|
|
||||||
private int storeSelection;
|
private int storeSelection;
|
||||||
private int sortMode;
|
private int sortMode;
|
||||||
private boolean descending;
|
private boolean descending;
|
||||||
private ArrayList<String> stores;
|
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 SortDialogFragment(int storeSelection, ArrayList<String> stores, int sortMode, boolean descending) {
|
public SortDialogFragment(int storeSelection, ArrayList<String> stores, int sortMode, boolean descending, double maxProductPrice, double minPrice, double maxPrice) {
|
||||||
this.storeSelection = storeSelection;
|
this.storeSelection = storeSelection;
|
||||||
this.stores = stores;
|
this.stores = stores;
|
||||||
this.sortMode = sortMode;
|
this.sortMode = sortMode;
|
||||||
this.descending = descending;
|
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() {
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
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() {
|
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
|
||||||
@ -91,7 +105,7 @@ public class SortDialogFragment extends DialogFragment {
|
|||||||
sortDirectionButton.setImageResource(R.drawable.ic_baseline_arrow_upward_50);
|
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() {
|
sortDirectionButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@ -125,9 +139,7 @@ public class SortDialogFragment extends DialogFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNothingSelected(AdapterView<?> parent) {
|
public void onNothingSelected(AdapterView<?> parent) {}
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disable the direction button if they have the default sorting mode selected
|
// Disable the direction button if they have the default sorting mode selected
|
||||||
@ -136,6 +148,25 @@ public class SortDialogFragment extends DialogFragment {
|
|||||||
sortDirectionButton.setEnabled(false);
|
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();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="100dp"
|
android:layout_height="wrap_content"
|
||||||
android:paddingStart="15dp">
|
android:paddingStart="15dp">
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
@ -50,4 +50,45 @@
|
|||||||
android:src="@drawable/ic_baseline_arrow_upward_50"/>
|
android:src="@drawable/ic_baseline_arrow_upward_50"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_price_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginStart="15dp"
|
||||||
|
android:text="Price" />
|
||||||
|
|
||||||
|
<com.crystal.crystalrangeseekbar.widgets.CrystalRangeSeekbar
|
||||||
|
android:id="@+id/price_range_seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="10dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_min_price"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginStart="15dp"
|
||||||
|
android:text="$00.00" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_max_price"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginEnd="15dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:text="$00.00" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
Loading…
Reference in New Issue
Block a user