diff --git a/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java b/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java new file mode 100644 index 0000000..e12eb39 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/FilterDialogFragment.java @@ -0,0 +1,113 @@ +package com.example.listify; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +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(ArrayList selectedStores, double minPrice, double maxPrice); + } + + public OnFilterListener onFilterListener; + + CrystalRangeSeekbar priceSeekbar; + CheckBoxListViewAdapter checkBoxAdapter; + + 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(ArrayList selectedStores, ArrayList stores, double maxProductPrice, double minPrice, double maxPrice) { + this.selectedStores = selectedStores; + this.stores = stores; + this.maxProductPrice = maxProductPrice; + this.minPrice = minPrice; + this.maxPrice = maxPrice; + } + + + @Override + public Dialog onCreateDialog(final Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Get the layout inflater + LayoutInflater inflater = requireActivity().getLayoutInflater(); + + // Inflate and set the layout for the dialog + // Pass null as the parent view because its going in the dialog layout + View root = inflater.inflate(R.layout.dialog_filter, null); + builder.setView(root) + // Add action buttons + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + selectedStores = checkBoxAdapter.getChecked(); + onFilterListener.sendFilter(selectedStores, priceSeekbar.getSelectedMinValue().doubleValue(), priceSeekbar.getSelectedMaxValue().doubleValue()); + } + }) + .setNegativeButton("cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + FilterDialogFragment.this.getDialog().cancel(); + } + }); + + ListView storesList = root.findViewById(R.id.store_name_list); + + // Create arraylist of stores from search results + ArrayList storeChoices = new ArrayList<>(stores); + + // 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); + 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(); + } + + // Required to extend DialogFragment + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + try { + onFilterListener = (OnFilterListener) getActivity(); + } catch (ClassCastException e) { + Log.e("FilterDialogFragment", "onAttach: ClassCastException: " + e.getMessage()); + } + } +} diff --git a/Listify/app/src/main/java/com/example/listify/ListPage.java b/Listify/app/src/main/java/com/example/listify/ListPage.java index af88aa3..6f719d7 100644 --- a/Listify/app/src/main/java/com/example/listify/ListPage.java +++ b/Listify/app/src/main/java/com/example/listify/ListPage.java @@ -225,6 +225,7 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver { ArrayList pQuantity; ArrayList pImages; + MyAdapter (Context c, ArrayList names, ArrayList stores, ArrayList prices, ArrayList quantity, ArrayList images) { super(c, R.layout.activity_listproductentry, R.id.productView, names); context = c; diff --git a/Listify/app/src/main/java/com/example/listify/MainActivity.java b/Listify/app/src/main/java/com/example/listify/MainActivity.java index dd6d2bc..fef669e 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -190,18 +190,6 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF return NavigationUI.navigateUp(navController, mAppBarConfiguration) || super.onSupportNavigateUp(); } - // This function only exists for the create new list option in hamburger menu - public void onClickCreateList(MenuItem m) { - m.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - CreateListDialogFragment createListDialogFragment = new CreateListDialogFragment(); - createListDialogFragment.show(getSupportFragmentManager(), "Create New List"); - return false; - } - }); - } - public void onClickSignout(MenuItem m) { m.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override 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 0421b58..96e1fa1 100644 --- a/Listify/app/src/main/java/com/example/listify/SearchResults.java +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -3,6 +3,8 @@ import android.content.Intent; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; @@ -23,28 +25,35 @@ import java.util.Properties; import static com.example.listify.MainActivity.am; -public class SearchResults extends AppCompatActivity implements SortDialogFragment.OnSortingListener, Requestor.Receiver { +public class SearchResults extends AppCompatActivity implements FilterDialogFragment.OnFilterListener, SortDialogFragment.OnSortListener, Requestor.Receiver { + private ListView listView; + private MenuItem filterItem; private ProgressBar loadingSearch; private SearchResultsListAdapter searchResultsListAdapter; private List resultsProductList = new ArrayList<>(); private List resultsProductListSorted = new ArrayList<>(); private ArrayList stores = new ArrayList<>(); - private int storeSelection; - private int sortMode; + private ArrayList selectedStores = new ArrayList<>(); + private SortModes sortMode = SortModes.NONE; private boolean descending; private double minPrice = 0; private double maxPrice = -1; @Override - public void sendSort(int storeSelection, int sortMode, boolean descending, double minPrice, double maxPrice) { - this.storeSelection = storeSelection; - this.sortMode = sortMode; - this.descending = descending; + public void sendFilter(ArrayList selectedStores, double minPrice, double maxPrice) { + this.selectedStores = selectedStores; this.minPrice = minPrice; this.maxPrice = maxPrice; sortResults(); } + @Override + public void sendSort(SortModes sortMode, boolean descending) { + this.sortMode = sortMode; + this.descending = descending; + sortResults(); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -120,22 +129,27 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme return false; } }); + } - // 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() { + @Override + public boolean onCreateOptionsMenu(Menu menu) { + //Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.search, menu); + MenuItem sortItem = menu.findItem(R.id.action_sort); + sortItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override - public void onClick(View v) { - // Sort the store list - stores.sort(new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1.compareTo(o2); - } - }); + public boolean onMenuItemClick(MenuItem item) { + SortDialogFragment sortDialog = new SortDialogFragment(sortMode, descending); + sortDialog.show(getSupportFragmentManager(), "Sort Dialog"); + return false; + } + }); + // TODO: Reset upper and lower limits on price filter when a new search is made + filterItem = menu.findItem(R.id.action_filter); + filterItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { // Determine the max price for the price slider double maxProductPrice; if (resultsProductList.isEmpty()) { @@ -159,10 +173,18 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme // 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"); + FilterDialogFragment sortDialog = new FilterDialogFragment(selectedStores, stores, maxProductPrice, minPrice, maxPrice); + sortDialog.show(getSupportFragmentManager(), "Filter Dialog"); + return false; } }); + + // Disable filtering by default until a search is made + if (resultsProductList.isEmpty()) { + filterItem.setEnabled(false); + } + + return true; } // Override default phone back button to add animation @@ -200,10 +222,11 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme // Sort based on mode switch (this.sortMode) { - case 0: + case NONE: // Do nothing break; - case 1: + + case NAME: resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { @@ -211,8 +234,8 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme } }); break; - - case 2: + + case PRICE: resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { @@ -227,7 +250,7 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme }); break; - case 3: + case STORE: resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { @@ -236,7 +259,7 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme }); break; - case 4: + case UPC: resultsProductListSorted.sort(new Comparator() { @Override public int compare(Product a, Product b) { @@ -247,7 +270,7 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme } // Flip the list if descending is selected - if (this.sortMode != 0 & this.descending) { + if (this.descending) { for (int i = 0; i < resultsProductListSorted.size() / 2; i++) { Product temp = resultsProductListSorted.get(i); resultsProductListSorted.set(i, resultsProductListSorted.get(resultsProductListSorted.size() - i - 1)); @@ -256,10 +279,10 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme } // 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); } }); @@ -317,8 +340,24 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme } } + // 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); + + // Filtering should only be allowed if there are items in the results + runOnUiThread(new Runnable() { + @Override + public void run() { + if (resultsProductList.isEmpty()) { + filterItem.setEnabled(false); + } else { + filterItem.setEnabled(true); + } + } + }); // Apply selected sorting to the list sortResults(); 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 7cc71a4..e76a43e 100644 --- a/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java +++ b/Listify/app/src/main/java/com/example/listify/SortDialogFragment.java @@ -1,56 +1,41 @@ package com.example.listify; import android.app.Dialog; import android.content.Context; -import android.content.DialogInterface; 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.ImageButton; -import android.widget.Spinner; +import android.widget.LinearLayout; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SwitchCompat; 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, double minPrice, double maxPrice); + public interface OnSortListener { + void sendSort(SortModes sortMode, boolean descending); } - public OnSortingListener onSortingListener; + public OnSortListener onSortListener; - CrystalRangeSeekbar priceSeekbar; - - private int storeSelection; - private int sortMode; + private SortModes 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, double maxProductPrice, double minPrice, double maxPrice) { - this.storeSelection = storeSelection; - this.stores = stores; + TextView tvSortNone; + TextView tvSortName; + TextView tvSortPrice; + TextView tvSortStore; + SwitchCompat swDescending; + + public SortDialogFragment(SortModes sortMode, boolean descending) { this.sortMode = sortMode; this.descending = descending; - this.maxProductPrice = maxProductPrice; - this.minPrice = minPrice; - this.maxPrice = maxPrice; } + // TODO: Sorting should scroll the user back to the top of the page @Override public Dialog onCreateDialog(final Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); @@ -60,122 +45,105 @@ public class SortDialogFragment extends DialogFragment { // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout View root = inflater.inflate(R.layout.dialog_sort, null); - builder.setView(root) - // Add action buttons - .setPositiveButton("OK", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - onSortingListener.sendSort(storeSelection, sortMode, descending, priceSeekbar.getSelectedMinValue().doubleValue(), priceSeekbar.getSelectedMaxValue().doubleValue()); - } - }) - .setNegativeButton("cancel", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - SortDialogFragment.this.getDialog().cancel(); - } - }); + builder.setView(root); - 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); + tvSortNone = (TextView) root.findViewById(R.id.sort_none); + tvSortName = (TextView) root.findViewById(R.id.sort_name); + tvSortPrice = (TextView) root.findViewById(R.id.sort_price); + tvSortStore = (TextView) root.findViewById(R.id.sort_store); + LinearLayout llDescendingContainer = (LinearLayout) root.findViewById(R.id.descending_container); + swDescending = (SwitchCompat) root.findViewById(R.id.switch_descending); + + switch (this.sortMode) { + case NONE: + tvSortNone.setBackgroundColor(getResources().getColor(R.color.colorAccent)); + break; + case NAME: + tvSortName.setBackgroundColor(getResources().getColor(R.color.colorAccent)); + break; + case PRICE: + tvSortPrice.setBackgroundColor(getResources().getColor(R.color.colorAccent)); + break; + case STORE: + tvSortStore.setBackgroundColor(getResources().getColor(R.color.colorAccent)); + break; } - // 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; - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - }); - - // Change the sort arrow to be pointing up or down based on ascending or descending - final ImageButton sortDirectionButton = root.findViewById(R.id.sort_direction_button); - if (descending) { - sortDirectionButton.setImageResource(R.drawable.ic_baseline_arrow_downward_50); - } else { - sortDirectionButton.setImageResource(R.drawable.ic_baseline_arrow_upward_50); + if (this.descending) { + swDescending.setChecked(true); } - // Change arrow pointing direction whenever the user clicks the button - sortDirectionButton.setOnClickListener(new View.OnClickListener() { + tvSortNone.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (descending) { - descending = false; - sortDirectionButton.setImageResource(R.drawable.ic_baseline_arrow_upward_50); - } else { - descending = true; - sortDirectionButton.setImageResource(R.drawable.ic_baseline_arrow_downward_50); - } + handleClicked(tvSortNone, SortModes.NONE, swDescending.isChecked()); } }); - // Create the sort mode selection dropdown - Spinner sortDropdown = (Spinner) root.findViewById(R.id.sort_mode_dropdown); - String[] items = new String[] {"", "Name", "Price", "Store"}; - ArrayAdapter adapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_dropdown_item, items); - sortDropdown.setAdapter(adapter); - sortDropdown.setSelection(this.sortMode); - sortDropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + tvSortName.setOnClickListener(new View.OnClickListener() { @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - sortMode = position; - - // Update the sort direction button - if (position == 0) { - sortDirectionButton.setEnabled(false); - } else { - sortDirectionButton.setEnabled(true); - } + public void onClick(View v) { + handleClicked(tvSortName, SortModes.NAME, swDescending.isChecked()); } - - @Override - public void onNothingSelected(AdapterView parent) {} }); - // Disable the direction button if they have the default sorting mode selected - // Ascending and Descending are mostly irrelevant in the default sort mode - if (sortDropdown.getSelectedItemPosition() == 0) { - 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() { + tvSortPrice.setOnClickListener(new View.OnClickListener() { @Override - public void valueChanged(Number minValue, Number maxValue) { - tvMin.setText(String.format("$%.2f", minValue.doubleValue())); - tvMax.setText(String.format("$%.2f", maxValue.doubleValue())); + public void onClick(View v) { + handleClicked(tvSortPrice, SortModes.PRICE, swDescending.isChecked()); + } + }); + + tvSortStore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + handleClicked(tvSortStore, SortModes.STORE, swDescending.isChecked()); + } + }); + + // TODO: set onclick listener for descending switch + llDescendingContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + System.out.println("linear"); + swDescending.performClick(); +// handleClicked(sortMode, swDescending.isChecked()); + } + }); + + swDescending.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + System.out.println("switch"); + descending = swDescending.isChecked(); + onSortListener.sendSort(sortMode, swDescending.isChecked()); } }); return builder.create(); } + void handleClicked(TextView tvSelected, SortModes sortMode, boolean descending) { + this.sortMode = sortMode; + this.descending = descending; + + tvSortNone.setBackgroundColor(getResources().getColor(R.color.white)); + tvSortName.setBackgroundColor(getResources().getColor(R.color.white)); + tvSortPrice.setBackgroundColor(getResources().getColor(R.color.white)); + tvSortStore.setBackgroundColor(getResources().getColor(R.color.white)); + + tvSelected.setBackgroundColor(getResources().getColor(R.color.colorAccent)); + onSortListener.sendSort(sortMode, descending); + +// SortDialogFragment.this.getDialog().cancel(); + } + // Required to extend DialogFragment @Override public void onAttach(@NonNull Context context) { super.onAttach(context); try { - onSortingListener = (OnSortingListener) getActivity(); + onSortListener = (OnSortListener) getActivity(); } catch (ClassCastException e) { Log.e("SortDialogFragment", "onAttach: ClassCastException: " + e.getMessage()); } diff --git a/Listify/app/src/main/java/com/example/listify/SortModes.java b/Listify/app/src/main/java/com/example/listify/SortModes.java new file mode 100644 index 0000000..6c490a3 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/SortModes.java @@ -0,0 +1,9 @@ +package com.example.listify; + +public enum SortModes { + NONE, + NAME, + PRICE, + STORE, + UPC +} 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/activity_search_results.xml b/Listify/app/src/main/res/layout/activity_search_results.xml index 2d8356e..3850f4d 100644 --- a/Listify/app/src/main/res/layout/activity_search_results.xml +++ b/Listify/app/src/main/res/layout/activity_search_results.xml @@ -23,10 +23,12 @@ android:id="@+id/backToHomeButton" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1" + android:translationX="-10dp" + android:padding="10dp" app:srcCompat="@drawable/abc_vector_test" android:background="@null" - android:contentDescription="@string/backButton"/> + android:contentDescription="@string/backButton" + android:foreground="?android:attr/selectableItemBackgroundBorderless"/> - - diff --git a/Listify/app/src/main/res/layout/app_bar_home.xml b/Listify/app/src/main/res/layout/app_bar_home.xml index 285fb12..d124049 100644 --- a/Listify/app/src/main/res/layout/app_bar_home.xml +++ b/Listify/app/src/main/res/layout/app_bar_home.xml @@ -19,13 +19,15 @@ app:popupTheme="@style/AppTheme.PopupOverlay" > + android:background="@null" + android:foreground="?android:attr/selectableItemBackgroundBorderless"/> diff --git a/Listify/app/src/main/res/layout/dialog_filter.xml b/Listify/app/src/main/res/layout/dialog_filter.xml new file mode 100644 index 0000000..7e6afc5 --- /dev/null +++ b/Listify/app/src/main/res/layout/dialog_filter.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/dialog_sort.xml b/Listify/app/src/main/res/layout/dialog_sort.xml index 6a6d5b1..af88f7d 100644 --- a/Listify/app/src/main/res/layout/dialog_sort.xml +++ b/Listify/app/src/main/res/layout/dialog_sort.xml @@ -1,93 +1,104 @@ + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="30dp"> + + + + + + android:id="@+id/sort_name" + android:layout_width="match_parent" + android:layout_height="50dp" + android:text="Name" + android:textSize="16sp" + android:textColor="@android:color/black" + android:paddingStart="16dp" + android:gravity="center_vertical" + android:clickable="true" + android:focusable="true" + android:foreground="?attr/selectableItemBackgroundBorderless"/> - + + android:id="@+id/sort_price" + android:layout_width="match_parent" + android:layout_height="50dp" + android:text="Price" + android:textSize="16sp" + android:textColor="@android:color/black" + android:paddingStart="16dp" + android:gravity="center_vertical" + android:clickable="true" + android:focusable="true" + android:foreground="?attr/selectableItemBackgroundBorderless"/> + + + + + + - - - - - - - - - - - - + android:layout_height="50dp" + android:gravity="center_vertical" + android:clickable="true" + android:focusable="true" + android:foreground="?attr/selectableItemBackgroundBorderless" + android:soundEffectsEnabled="false"> - + android:text="Descending" + android:textSize="16sp" + android:textColor="@android:color/black" + android:paddingStart="16dp"/> + diff --git a/Listify/app/src/main/res/layout/filter_store_item.xml b/Listify/app/src/main/res/layout/filter_store_item.xml new file mode 100644 index 0000000..0a34aae --- /dev/null +++ b/Listify/app/src/main/res/layout/filter_store_item.xml @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/shopping_lists_swipeable_name_item.xml b/Listify/app/src/main/res/layout/shopping_lists_swipeable_name_item.xml index 2bba1d9..98f9613 100644 --- a/Listify/app/src/main/res/layout/shopping_lists_swipeable_name_item.xml +++ b/Listify/app/src/main/res/layout/shopping_lists_swipeable_name_item.xml @@ -5,7 +5,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - app:dragEdge="right" + app:dragEdge="left" app:mode="same_level"> + + + + + + + + + diff --git a/Listify/app/src/main/res/values/colors.xml b/Listify/app/src/main/res/values/colors.xml index a9055a6..84a11b5 100644 --- a/Listify/app/src/main/res/values/colors.xml +++ b/Listify/app/src/main/res/values/colors.xml @@ -11,4 +11,5 @@ #ebeef0 #1c9ef4 #e6e6e6 + #ffffffff \ No newline at end of file