Multiple Filters and Sorting in Android Android Android Projects Java by Rajesh Kumar Sahanee - February 16, 2020March 24, 20200 Post Views: 8,770 Hello Friends, today we are going to see multiple filters and sorting in Android. In multiple filters we basically choose multiple values from multiple available filter options and then filter the list. We can see this type of feature in flipkart or any other shopping app where we can filter products by color, size, price, etc. Here we are going to create multiple filter options almost similar to flipkart filter optionĀ as well as sorting so that we can sort products by name, size and price. Here in this example we’ll also learn the use of Comparator interface for sorting. So, here is the code MainActivity.java MainActivity.java Java package com.zatackcoder.filtersortexample; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.RadioGroup; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.adaptors.ItemAdapter; import com.zatackcoder.filtersortexample.classes.Filter; import com.zatackcoder.filtersortexample.classes.Item; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class MainActivity extends AppCompatActivity { List<Item> items = new ArrayList<Item>(); private RecyclerView mRecyclerView; private RecyclerView.Adapter mAdapter; private RecyclerView.LayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = findViewById(R.id.recycler_view); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLayoutManager); items.add(new Item("Item 1", "Red", 10, 100.00)); items.add(new Item("Item 2", "Red", 12, 100.00)); items.add(new Item("Item 3", "Red", 14, 100.00)); items.add(new Item("Item 4", "Red", 16, 150.00)); items.add(new Item("Item 5", "Red", 18, 170.00)); items.add(new Item("Item 6", "Green", 20, 190.00)); items.add(new Item("Item 7", "Green", 10, 100.00)); items.add(new Item("Item 8", "Green", 12, 200.00)); items.add(new Item("Item 9", "Green", 14, 210.00)); items.add(new Item("Item 10", "Green", 16, 240.00)); items.add(new Item("Item 11", "Blue", 18, 250.00)); items.add(new Item("Item 12", "Blue", 20, 280.00)); items.add(new Item("Item 13", "Blue", 10, 300.00)); items.add(new Item("Item 14", "Blue", 12, 150.00)); items.add(new Item("Item 15", "White", 10, 170.00)); if (!Preferences.filters.isEmpty()) { ArrayList<Item> filteredItems = new ArrayList<Item>(); List<String> colors = Preferences.filters.get(Filter.INDEX_COLOR).getSelected(); List<String> sizes = Preferences.filters.get(Filter.INDEX_SIZE).getSelected(); List<String> prices = Preferences.filters.get(Filter.INDEX_PRICE).getSelected(); for (Item item : items) { boolean colorMatched = true; if (colors.size() > 0 && !colors.contains(item.getColor())) { colorMatched = false; } boolean sizeMatched = true; if (sizes.size() > 0 && !sizes.contains(item.getSize().toString())) { sizeMatched = false; } boolean priceMatched = true; if (prices.size() > 0 && !priceContains(prices, item.getPrice())) { priceMatched = false; } if (colorMatched && sizeMatched && priceMatched) { filteredItems.add(item); } } items = filteredItems; } mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); final LinearLayout sortContainerBackLL = findViewById(R.id.sortContainerBackLL); final LinearLayout sortContainerLL = findViewById(R.id.sortContainerLL); //sortContainerLL.setTranslationY(-sortContainerLL.getHeight()); sortContainerBackLL.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sortContainerLL.animate() .translationY(-sortContainerLL.getHeight()) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { sortContainerLL.animate().setListener(null); sortContainerBackLL.setVisibility(View.GONE); } }); } }); Button sortB = findViewById(R.id.sortB); sortB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sortContainerBackLL.setVisibility(View.VISIBLE); sortContainerLL.animate().translationY(0); } }); Button filterB = findViewById(R.id.filterB); filterB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, FilterActivity.class)); } }); RadioGroup sortRG = findViewById(R.id.sortRG); sortRG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.sortByName: Item[] itemsArr1 = new Item[items.size()]; itemsArr1 = items.toArray(itemsArr1); Arrays.sort(itemsArr1, Item.nameComparator); items = Arrays.asList(itemsArr1); mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); break; case R.id.sortBySize: Item[] itemsArr2 = new Item[items.size()]; itemsArr2 = items.toArray(itemsArr2); Arrays.sort(itemsArr2, Item.sizeComparator); items = Arrays.asList(itemsArr2); mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); break; case R.id.sortByPrice: Item[] itemsArr3 = new Item[items.size()]; itemsArr3 = items.toArray(itemsArr3); Arrays.sort(itemsArr3, Item.priceComparator); items = Arrays.asList(itemsArr3); mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); break; } sortContainerLL.animate() .translationY(-sortContainerLL.getHeight()) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { sortContainerLL.animate().setListener(null); sortContainerBackLL.setVisibility(View.GONE); } }); } }); } private boolean priceContains(List<String> prices, Double price) { boolean flag = false; for (String p : prices) { String tmpPrices[] = p.split("-"); if (price >= Double.valueOf(tmpPrices[0]) && price <= Double.valueOf(tmpPrices[1])) { flag = true; break; } } return flag; } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 package com.zatackcoder.filtersortexample; import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.LinearLayout;import android.widget.RadioGroup; import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.adaptors.ItemAdapter;import com.zatackcoder.filtersortexample.classes.Filter;import com.zatackcoder.filtersortexample.classes.Item; import java.util.ArrayList;import java.util.Arrays;import java.util.List; public class MainActivity extends AppCompatActivity { List<Item> items = new ArrayList<Item>(); private RecyclerView mRecyclerView; private RecyclerView.Adapter mAdapter; private RecyclerView.LayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = findViewById(R.id.recycler_view); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLayoutManager); items.add(new Item("Item 1", "Red", 10, 100.00)); items.add(new Item("Item 2", "Red", 12, 100.00)); items.add(new Item("Item 3", "Red", 14, 100.00)); items.add(new Item("Item 4", "Red", 16, 150.00)); items.add(new Item("Item 5", "Red", 18, 170.00)); items.add(new Item("Item 6", "Green", 20, 190.00)); items.add(new Item("Item 7", "Green", 10, 100.00)); items.add(new Item("Item 8", "Green", 12, 200.00)); items.add(new Item("Item 9", "Green", 14, 210.00)); items.add(new Item("Item 10", "Green", 16, 240.00)); items.add(new Item("Item 11", "Blue", 18, 250.00)); items.add(new Item("Item 12", "Blue", 20, 280.00)); items.add(new Item("Item 13", "Blue", 10, 300.00)); items.add(new Item("Item 14", "Blue", 12, 150.00)); items.add(new Item("Item 15", "White", 10, 170.00)); if (!Preferences.filters.isEmpty()) { ArrayList<Item> filteredItems = new ArrayList<Item>(); List<String> colors = Preferences.filters.get(Filter.INDEX_COLOR).getSelected(); List<String> sizes = Preferences.filters.get(Filter.INDEX_SIZE).getSelected(); List<String> prices = Preferences.filters.get(Filter.INDEX_PRICE).getSelected(); for (Item item : items) { boolean colorMatched = true; if (colors.size() > 0 && !colors.contains(item.getColor())) { colorMatched = false; } boolean sizeMatched = true; if (sizes.size() > 0 && !sizes.contains(item.getSize().toString())) { sizeMatched = false; } boolean priceMatched = true; if (prices.size() > 0 && !priceContains(prices, item.getPrice())) { priceMatched = false; } if (colorMatched && sizeMatched && priceMatched) { filteredItems.add(item); } } items = filteredItems; } mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); final LinearLayout sortContainerBackLL = findViewById(R.id.sortContainerBackLL); final LinearLayout sortContainerLL = findViewById(R.id.sortContainerLL); //sortContainerLL.setTranslationY(-sortContainerLL.getHeight()); sortContainerBackLL.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sortContainerLL.animate() .translationY(-sortContainerLL.getHeight()) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { sortContainerLL.animate().setListener(null); sortContainerBackLL.setVisibility(View.GONE); } }); } }); Button sortB = findViewById(R.id.sortB); sortB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sortContainerBackLL.setVisibility(View.VISIBLE); sortContainerLL.animate().translationY(0); } }); Button filterB = findViewById(R.id.filterB); filterB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, FilterActivity.class)); } }); RadioGroup sortRG = findViewById(R.id.sortRG); sortRG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.sortByName: Item[] itemsArr1 = new Item[items.size()]; itemsArr1 = items.toArray(itemsArr1); Arrays.sort(itemsArr1, Item.nameComparator); items = Arrays.asList(itemsArr1); mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); break; case R.id.sortBySize: Item[] itemsArr2 = new Item[items.size()]; itemsArr2 = items.toArray(itemsArr2); Arrays.sort(itemsArr2, Item.sizeComparator); items = Arrays.asList(itemsArr2); mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); break; case R.id.sortByPrice: Item[] itemsArr3 = new Item[items.size()]; itemsArr3 = items.toArray(itemsArr3); Arrays.sort(itemsArr3, Item.priceComparator); items = Arrays.asList(itemsArr3); mAdapter = new ItemAdapter(getApplicationContext(), items); mRecyclerView.setAdapter(mAdapter); break; } sortContainerLL.animate() .translationY(-sortContainerLL.getHeight()) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { sortContainerLL.animate().setListener(null); sortContainerBackLL.setVisibility(View.GONE); } }); } }); } private boolean priceContains(List<String> prices, Double price) { boolean flag = false; for (String p : prices) { String tmpPrices[] = p.split("-"); if (price >= Double.valueOf(tmpPrices[0]) && price <= Double.valueOf(tmpPrices[1])) { flag = true; break; } } return flag; }} activity_main.xml activity_main.xml XHTML <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0" android:orientation="horizontal"> <Button android:id="@+id/sortB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:drawableLeft="@drawable/ic_sort_black_24dp" android:text="Sort" /> <Button android:id="@+id/filterB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:drawableLeft="@drawable/ic_filter_list_black_24dp" android:text="Filter" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/sortContainerBackLL" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#C4000000" android:orientation="vertical" android:visibility="gone" tools:ignore="MissingConstraints" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp"> <LinearLayout android:id="@+id/sortContainerLL" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFFFF" android:orientation="vertical" tools:ignore="MissingConstraints" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="SORT BY" android:textSize="15dp" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#929191" /> <RadioGroup android:id="@+id/sortRG" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <RadioButton android:id="@+id/sortByName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layoutDirection="rtl" android:text="Name" /> <RadioButton android:id="@+id/sortBySize" android:layout_width="match_parent" android:layout_height="wrap_content" android:layoutDirection="rtl" android:text="Size" /> <RadioButton android:id="@+id/sortByPrice" android:layout_width="match_parent" android:layout_height="wrap_content" android:layoutDirection="rtl" android:text="Price" /> </RadioGroup> </LinearLayout> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0" android:orientation="horizontal"> <Button android:id="@+id/sortB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:drawableLeft="@drawable/ic_sort_black_24dp" android:text="Sort" /> <Button android:id="@+id/filterB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:drawableLeft="@drawable/ic_filter_list_black_24dp" android:text="Filter" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/sortContainerBackLL" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#C4000000" android:orientation="vertical" android:visibility="gone" tools:ignore="MissingConstraints" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp"> <LinearLayout android:id="@+id/sortContainerLL" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFFFF" android:orientation="vertical" tools:ignore="MissingConstraints" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="SORT BY" android:textSize="15dp" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#929191" /> <RadioGroup android:id="@+id/sortRG" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <RadioButton android:id="@+id/sortByName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layoutDirection="rtl" android:text="Name" /> <RadioButton android:id="@+id/sortBySize" android:layout_width="match_parent" android:layout_height="wrap_content" android:layoutDirection="rtl" android:text="Size" /> <RadioButton android:id="@+id/sortByPrice" android:layout_width="match_parent" android:layout_height="wrap_content" android:layoutDirection="rtl" android:text="Price" /> </RadioGroup> </LinearLayout> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> FilterActivity.java FilterActivity.java Java package com.zatackcoder.filtersortexample; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.adaptors.FilterAdapter; import com.zatackcoder.filtersortexample.classes.Filter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class FilterActivity extends AppCompatActivity { RecyclerView filterRV; RecyclerView filterValuesRV; FilterAdapter filterAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_filter); initControls(); } private void initControls() { filterRV = findViewById(R.id.filterRV); filterValuesRV = findViewById(R.id.filterValuesRV); filterRV.setLayoutManager(new LinearLayoutManager(this)); filterValuesRV.setLayoutManager(new LinearLayoutManager(this)); List<String> colors = Arrays.asList(new String[]{"Red", "Green", "Blue", "White"}); if (!Preferences.filters.containsKey(Filter.INDEX_COLOR)) { Preferences.filters.put(Filter.INDEX_COLOR, new Filter("Color", colors, new ArrayList())); } List<String> sizes = Arrays.asList(new String[]{"10", "12", "14", "16", "18", "20"}); if (!Preferences.filters.containsKey(Filter.INDEX_SIZE)) { Preferences.filters.put(Filter.INDEX_SIZE, new Filter("Size", sizes, new ArrayList())); } List<String> prices = Arrays.asList(new String[]{"0-100", "101-200", "201-300"}); if (!Preferences.filters.containsKey(Filter.INDEX_PRICE)) { Preferences.filters.put(Filter.INDEX_PRICE, new Filter("Price", prices, new ArrayList())); } filterAdapter = new FilterAdapter(getApplicationContext(), Preferences.filters, filterValuesRV); filterRV.setAdapter(filterAdapter); Button clearB = findViewById(R.id.clearB); clearB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Preferences.filters.get(Filter.INDEX_COLOR).setSelected(new ArrayList()); Preferences.filters.get(Filter.INDEX_SIZE).setSelected(new ArrayList()); Preferences.filters.get(Filter.INDEX_PRICE).setSelected(new ArrayList()); startActivity(new Intent(FilterActivity.this, MainActivity.class)); } }); Button applyB = findViewById(R.id.applyB); applyB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(FilterActivity.this, MainActivity.class)); } }); } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 package com.zatackcoder.filtersortexample; import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button; import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.adaptors.FilterAdapter;import com.zatackcoder.filtersortexample.classes.Filter; import java.util.ArrayList;import java.util.Arrays;import java.util.List; public class FilterActivity extends AppCompatActivity { RecyclerView filterRV; RecyclerView filterValuesRV; FilterAdapter filterAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_filter); initControls(); } private void initControls() { filterRV = findViewById(R.id.filterRV); filterValuesRV = findViewById(R.id.filterValuesRV); filterRV.setLayoutManager(new LinearLayoutManager(this)); filterValuesRV.setLayoutManager(new LinearLayoutManager(this)); List<String> colors = Arrays.asList(new String[]{"Red", "Green", "Blue", "White"}); if (!Preferences.filters.containsKey(Filter.INDEX_COLOR)) { Preferences.filters.put(Filter.INDEX_COLOR, new Filter("Color", colors, new ArrayList())); } List<String> sizes = Arrays.asList(new String[]{"10", "12", "14", "16", "18", "20"}); if (!Preferences.filters.containsKey(Filter.INDEX_SIZE)) { Preferences.filters.put(Filter.INDEX_SIZE, new Filter("Size", sizes, new ArrayList())); } List<String> prices = Arrays.asList(new String[]{"0-100", "101-200", "201-300"}); if (!Preferences.filters.containsKey(Filter.INDEX_PRICE)) { Preferences.filters.put(Filter.INDEX_PRICE, new Filter("Price", prices, new ArrayList())); } filterAdapter = new FilterAdapter(getApplicationContext(), Preferences.filters, filterValuesRV); filterRV.setAdapter(filterAdapter); Button clearB = findViewById(R.id.clearB); clearB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Preferences.filters.get(Filter.INDEX_COLOR).setSelected(new ArrayList()); Preferences.filters.get(Filter.INDEX_SIZE).setSelected(new ArrayList()); Preferences.filters.get(Filter.INDEX_PRICE).setSelected(new ArrayList()); startActivity(new Intent(FilterActivity.this, MainActivity.class)); } }); Button applyB = findViewById(R.id.applyB); applyB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(FilterActivity.this, MainActivity.class)); } }); }} activity_filter.xml activity_filter.xml XHTML <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FilterActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/filterRV" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0" android:background="#F2F2F2" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/filterValuesRV" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="#ffffff" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0" android:orientation="horizontal"> <Button android:id="@+id/clearB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Clear" /> <Button android:id="@+id/applyB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Apply" /> </LinearLayout> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FilterActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/filterRV" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="0" android:background="#F2F2F2" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/filterValuesRV" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="#ffffff" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0" android:orientation="horizontal"> <Button android:id="@+id/clearB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Clear" /> <Button android:id="@+id/applyB" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Apply" /> </LinearLayout> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> ItemAdapter.java ItemAdapter.java Java package com.zatackcoder.filtersortexample.adaptors; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.R; import com.zatackcoder.filtersortexample.classes.Item; import java.util.List; public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.MyViewHolder> { private Context context; private List<Item> items; public ItemAdapter(Context context, List<Item> items) { this.context = context; this.items = items; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false); MyViewHolder mvh = new MyViewHolder(view); return mvh; } @Override public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { myViewHolder.container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String message = "You clicked on " + items.get(position).getName() + " - color:" + items.get(position).getColor() + " | size:" + items.get(position).getSize() + " | price:" + items.get(position).getPrice(); Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } }); myViewHolder.name.setText(items.get(position).getName()); myViewHolder.color.setText("Color: " + items.get(position).getColor()); myViewHolder.size.setText("Size: " + items.get(position).getSize()); myViewHolder.price.setText("Price: " + items.get(position).getPrice()); } @Override public int getItemCount() { return items.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { View container; TextView name; TextView color; TextView size; TextView price; public MyViewHolder(View view) { super(view); container = view; name = view.findViewById(R.id.name); color = view.findViewById(R.id.color); size = view.findViewById(R.id.size); price = view.findViewById(R.id.price); } } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 package com.zatackcoder.filtersortexample.adaptors; import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.widget.Toast; import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.R;import com.zatackcoder.filtersortexample.classes.Item; import java.util.List; public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.MyViewHolder> { private Context context; private List<Item> items; public ItemAdapter(Context context, List<Item> items) { this.context = context; this.items = items; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false); MyViewHolder mvh = new MyViewHolder(view); return mvh; } @Override public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { myViewHolder.container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String message = "You clicked on " + items.get(position).getName() + " - color:" + items.get(position).getColor() + " | size:" + items.get(position).getSize() + " | price:" + items.get(position).getPrice(); Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } }); myViewHolder.name.setText(items.get(position).getName()); myViewHolder.color.setText("Color: " + items.get(position).getColor()); myViewHolder.size.setText("Size: " + items.get(position).getSize()); myViewHolder.price.setText("Price: " + items.get(position).getPrice()); } @Override public int getItemCount() { return items.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { View container; TextView name; TextView color; TextView size; TextView price; public MyViewHolder(View view) { super(view); container = view; name = view.findViewById(R.id.name); color = view.findViewById(R.id.color); size = view.findViewById(R.id.size); price = view.findViewById(R.id.price); } } } list_item.xml list_item.xml XHTML <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:background="#ffffff" android:clickable="true" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Name" android:textFontWeight="bold" android:textSize="15dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/color" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Color: Red" android:textSize="12dp" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_margin="5dp" android:background="#ADABAB" /> <TextView android:id="@+id/size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Size: 10" android:textSize="12dp" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_margin="5dp" android:background="#ADABAB" /> <TextView android:id="@+id/price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Price: 100" android:textSize="12dp" /> </LinearLayout> </LinearLayout> </LinearLayout> 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:background="#ffffff" android:clickable="true" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Name" android:textFontWeight="bold" android:textSize="15dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/color" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Color: Red" android:textSize="12dp" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_margin="5dp" android:background="#ADABAB" /> <TextView android:id="@+id/size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Size: 10" android:textSize="12dp" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_margin="5dp" android:background="#ADABAB" /> <TextView android:id="@+id/price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Price: 100" android:textSize="12dp" /> </LinearLayout> </LinearLayout> </LinearLayout> FilterAdapter.java FilterAdapter.java Java package com.zatackcoder.filtersortexample.adaptors; import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.classes.Filter; import com.zatackcoder.filtersortexample.R; import java.util.HashMap; public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.MyViewHolder> { private Context context; private HashMap<Integer, Filter> filters; private RecyclerView filterValuesRV; private int selectedPostion = 0; public FilterAdapter(Context context, HashMap<Integer, Filter> filters, RecyclerView filterValuesRV) { this.context = context; this.filters = filters; this.filterValuesRV = filterValuesRV; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.filter_item, viewGroup, false); MyViewHolder mvh = new MyViewHolder(view); return mvh; } @Override public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { myViewHolder.container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { filterValuesRV.setAdapter(new FilterValuesAdapter(context, position)); selectedPostion = position; notifyDataSetChanged(); } }); filterValuesRV.setAdapter(new FilterValuesAdapter(context, selectedPostion)); myViewHolder.container.setBackgroundColor(selectedPostion == position ? Color.WHITE : Color.TRANSPARENT); myViewHolder.title.setText(filters.get(position).getName()); } @Override public int getItemCount() { return filters.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { View container; TextView title; public MyViewHolder(View view) { super(view); container = view; title = view.findViewById(R.id.title); } } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 package com.zatackcoder.filtersortexample.adaptors; import android.content.Context;import android.graphics.Color;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView; import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.classes.Filter;import com.zatackcoder.filtersortexample.R; import java.util.HashMap; public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.MyViewHolder> { private Context context; private HashMap<Integer, Filter> filters; private RecyclerView filterValuesRV; private int selectedPostion = 0; public FilterAdapter(Context context, HashMap<Integer, Filter> filters, RecyclerView filterValuesRV) { this.context = context; this.filters = filters; this.filterValuesRV = filterValuesRV; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.filter_item, viewGroup, false); MyViewHolder mvh = new MyViewHolder(view); return mvh; } @Override public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { myViewHolder.container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { filterValuesRV.setAdapter(new FilterValuesAdapter(context, position)); selectedPostion = position; notifyDataSetChanged(); } }); filterValuesRV.setAdapter(new FilterValuesAdapter(context, selectedPostion)); myViewHolder.container.setBackgroundColor(selectedPostion == position ? Color.WHITE : Color.TRANSPARENT); myViewHolder.title.setText(filters.get(position).getName()); } @Override public int getItemCount() { return filters.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { View container; TextView title; public MyViewHolder(View view) { super(view); container = view; title = view.findViewById(R.id.title); } } } filter_item.xml filter_item.xml XHTML <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_marginRight="0dp" android:layout_marginBottom="5dp" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:orientation="vertical"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="Color" android:textFontWeight="bold" android:textSize="15dp" /> </LinearLayout> 1234567891011121314151617181920212223 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_marginRight="0dp" android:layout_marginBottom="5dp" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:orientation="vertical"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="Color" android:textFontWeight="bold" android:textSize="15dp" /> </LinearLayout> FilterValuesAdapter.java FilterValuesAdapter.java Java package com.zatackcoder.filtersortexample.adaptors; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.Preferences; import com.zatackcoder.filtersortexample.R; import com.zatackcoder.filtersortexample.classes.Filter; import java.util.List; public class FilterValuesAdapter extends RecyclerView.Adapter<FilterValuesAdapter.MyViewHolder> { private Context context; private Integer filterIndex; public FilterValuesAdapter(Context context, Integer filterIndex) { this.context = context; this.filterIndex = filterIndex; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.filter_value_item, viewGroup, false); MyViewHolder mvh = new MyViewHolder(view); return mvh; } @Override public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { final Filter tmpFilter = Preferences.filters.get(filterIndex); myViewHolder.value.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { List<String> selected = tmpFilter.getSelected(); if(myViewHolder.value.isChecked()) { selected.add(tmpFilter.getValues().get(position)); tmpFilter.setSelected(selected); } else { selected.remove(tmpFilter.getValues().get(position)); tmpFilter.setSelected(selected); } Preferences.filters.put(filterIndex, tmpFilter); } }); myViewHolder.value.setText(tmpFilter.getValues().get(position)); if(tmpFilter.getSelected().contains(tmpFilter.getValues().get(position))) { myViewHolder.value.setChecked(true); } } @Override public int getItemCount() { return Preferences.filters.get(filterIndex).getValues().size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { View container; CheckBox value; public MyViewHolder(View view) { super(view); container = view; value = view.findViewById(R.id.value); } } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 package com.zatackcoder.filtersortexample.adaptors; import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.CheckBox;import android.widget.Toast; import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView; import com.zatackcoder.filtersortexample.Preferences;import com.zatackcoder.filtersortexample.R;import com.zatackcoder.filtersortexample.classes.Filter; import java.util.List; public class FilterValuesAdapter extends RecyclerView.Adapter<FilterValuesAdapter.MyViewHolder> { private Context context; private Integer filterIndex; public FilterValuesAdapter(Context context, Integer filterIndex) { this.context = context; this.filterIndex = filterIndex; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.filter_value_item, viewGroup, false); MyViewHolder mvh = new MyViewHolder(view); return mvh; } @Override public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { final Filter tmpFilter = Preferences.filters.get(filterIndex); myViewHolder.value.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { List<String> selected = tmpFilter.getSelected(); if(myViewHolder.value.isChecked()) { selected.add(tmpFilter.getValues().get(position)); tmpFilter.setSelected(selected); } else { selected.remove(tmpFilter.getValues().get(position)); tmpFilter.setSelected(selected); } Preferences.filters.put(filterIndex, tmpFilter); } }); myViewHolder.value.setText(tmpFilter.getValues().get(position)); if(tmpFilter.getSelected().contains(tmpFilter.getValues().get(position))) { myViewHolder.value.setChecked(true); } } @Override public int getItemCount() { return Preferences.filters.get(filterIndex).getValues().size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { View container; CheckBox value; public MyViewHolder(View view) { super(view); container = view; value = view.findViewById(R.id.value); } } } filter_value_item.xml filter_value_item.xml XHTML <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:clickable="true" android:orientation="vertical"> <CheckBox android:id="@+id/value" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Red" android:textFontWeight="bold" android:textSize="15dp" /> </LinearLayout> 1234567891011121314151617 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:clickable="true" android:orientation="vertical"> <CheckBox android:id="@+id/value" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Red" android:textFontWeight="bold" android:textSize="15dp" /> </LinearLayout> Item.java Item.java Java package com.zatackcoder.filtersortexample.classes; import java.util.Comparator; public class Item { public static Comparator<Item> nameComparator = new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { return o1.getName().compareTo(o2.getName()); } }; public static Comparator<Item> sizeComparator = new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { return o1.getSize() - o2.getSize(); } }; public static Comparator<Item> priceComparator = new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { return (int) (o1.getPrice() - o2.getPrice()); } }; private String name; private String color; private Integer size; private Double price; public Item(String name, String color, Integer size, Double price) { this.name = name; this.color = color; this.size = size; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Integer getSize() { return size; } public void setSize(Integer size) { this.size = size; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 package com.zatackcoder.filtersortexample.classes; import java.util.Comparator; public class Item { public static Comparator<Item> nameComparator = new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { return o1.getName().compareTo(o2.getName()); } }; public static Comparator<Item> sizeComparator = new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { return o1.getSize() - o2.getSize(); } }; public static Comparator<Item> priceComparator = new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { return (int) (o1.getPrice() - o2.getPrice()); } }; private String name; private String color; private Integer size; private Double price; public Item(String name, String color, Integer size, Double price) { this.name = name; this.color = color; this.size = size; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Integer getSize() { return size; } public void setSize(Integer size) { this.size = size; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; }} Filter.java Filter.java Java package com.zatackcoder.filtersortexample.classes; import java.util.ArrayList; import java.util.List; public class Filter { public static Integer INDEX_COLOR = 0; public static Integer INDEX_SIZE = 1; public static Integer INDEX_PRICE = 2; private String name; private List<String> values; private List<String> selected; public Filter(String name, List<String> values, List<String> selected) { this.name = name; this.values = values; this.selected = selected; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getValues() { return values; } public void setValues(List<String> values) { this.values = values; } public List<String> getSelected() { return selected; } public void setSelected(List<String> selected) { this.selected = selected; } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344 package com.zatackcoder.filtersortexample.classes; import java.util.ArrayList;import java.util.List; public class Filter { public static Integer INDEX_COLOR = 0; public static Integer INDEX_SIZE = 1; public static Integer INDEX_PRICE = 2; private String name; private List<String> values; private List<String> selected; public Filter(String name, List<String> values, List<String> selected) { this.name = name; this.values = values; this.selected = selected; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getValues() { return values; } public void setValues(List<String> values) { this.values = values; } public List<String> getSelected() { return selected; } public void setSelected(List<String> selected) { this.selected = selected; }} Preferences.java Preferences.java Java package com.zatackcoder.filtersortexample; import com.zatackcoder.filtersortexample.classes.Filter; import java.util.HashMap; public abstract class Preferences { public static HashMap<Integer, Filter> filters = new HashMap<>(); } 123456789 package com.zatackcoder.filtersortexample; import com.zatackcoder.filtersortexample.classes.Filter; import java.util.HashMap; public abstract class Preferences { public static HashMap<Integer, Filter> filters = new HashMap<>();} Directory/Package Structure Video https://zatackcoder.com/wp-content/uploads/2020/02/FilterSortExample-Video.mp4 AndroidStudio Project Download FilterSortExample AndroidStudio Project 1 file(s) 13.09 MB Download Thanks for Stoping by If you find this helpful then please do share