search resultlist not getting set to recyclerview - android

i m implementing search functionality with realmData i got printed searched string but the searched string not getting set to recyclerview.
realm serchfilter return complete result and print it but return mFilteredList not getting set to recyclerview
package "";
public class FollowAdapter extends RecyclerView.Adapter<FollowAdapter.Holder> implements Filterable {
private Context context;
ActionListener actionListener;
InviteListener inviteListener;
private String TAG = getClass().getName();
List<ContactClass> realmList;
private List<ContactClass> mFilteredList;
public FollowAdapter(Context context, List<ContactClass> realmList) {
this.context = context;
this.realmList = realmList;
mFilteredList = realmList;
}
public InviteListener getInviteListener() {
return inviteListener;
}
public void setInviteListener(InviteListener inviteListener) {
this.inviteListener = inviteListener;
}
public ActionListener getActionListener() {
return actionListener;
}
public void setActionListener(ActionListener actionListener) {
this.actionListener = actionListener;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.follow_item, parent, false));
}
#Override
public void onBindViewHolder(final Holder holder, final int position) {
final ContactClass contactClass = realmList.get(position);
holder.contactName.setText(contactClass.getName());
Drawable drawable = ResourcesCompat.getDrawable(holder.itemView.getContext().getResources(), R.drawable.camera, null);
Glide.with(holder.itemView.getContext()).load(contactClass.getAvatar()).into(holder.contact_pic).onLoadFailed(drawable);
holder.contactNumber.setText(contactClass.getNumber());
}
}
#Override
public int getItemCount() {
return realmList.size();
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = realmList;
} else {
List<ContactClass> filteredList = new ArrayList<>();
Realm realm = Realm.getDefaultInstance();
RealmQuery<ContactClass> query = realm.where(ContactClass.class).contains("name", charString, Case.INSENSITIVE);
RealmResults<ContactClass> realmResults = query.findAll();
for (ContactClass c : realmResults) {
filteredList.add(c);
Log.e("filter", c.getName() + " " + c.getNumber() + " " + c.getId());
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
if (mFilteredList != null) {
Log.e("sized", mFilteredList.size() + "");
}
mFilteredList = (List<ContactClass>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class Holder extends RecyclerView.ViewHolder {
ImageView contact_pic;
TextView contactName, contactNumber;
AppCompatButton follow;
public Holder(View itemView) {
super(itemView);
contact_pic = itemView.findViewById(R.id.contact_pic);
contactName = itemView.findViewById(R.id.contact_name);
contactNumber = itemView.findViewById(R.id.contact_number);
follow = itemView.findViewById(R.id.btn_follow);
contactName.setSelected(true);
contactNumber.setSelected(true);
}
}}
code to search query
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
followAdapter.getFilter().filter(newText);
return false;
}

Related

Search View with RecyclerView on click show old data

I am doing Search view with RecyclerView every thing work fine like data show in RecyclerView on search data also filter and showing result but when i touch data it give old position means filter position not showing on toast, if we search typing z in search view it show all data start with z but when i click data start with z it show me on toast data which is old means data start with a
I am getting same problem with list there i found solution with ListView Object
list.getItemAtPosition this solve problem the same problem in RecyclerView
here is interface
public interface RecyclerViewClickListener {
public void recyclerViewListClicked(View v, int position);}
this code getting problem
recycleitemclicklistener = new RecyclerViewClickListener() {
#Override
public void recyclerViewListClicked(View v, int position) {
if (positionvalue.equals("CommonCustomer")) {
CommonSetterANDGetter getclick= commonSetterANDGetters.get(position);
Toast.makeText(maincontext, "denm"+ getclick.getValueNameCustomer()+getclick.getIdCustomer(), Toast.LENGTH_SHORT).show();
}
}
};
this is Adaptor
public class SearchAdapter extends
RecyclerView.Adapter<SearchAdapter.ViewHolder> implements Filterable {
private ArrayList<CommonSetterANDGetter> mArrayList;
private ArrayList<CommonSetterANDGetter> mFilteredList;
private String positionvalue = null;
RecyclerViewClickListener itemclicklistener;
Context maincontext;
public SearchAdapter(Context maincontext, ArrayList<CommonSetterANDGetter> arrayList, String positionvalue, RecyclerViewClickListener recycleitemclicklistener) {
this.maincontext = maincontext;
this.mArrayList = arrayList;
this.mFilteredList = arrayList;
this.itemclicklistener = recycleitemclicklistener;
this.positionvalue=positionvalue;
}
#Override
public SearchAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = null;
if(positionvalue.equals( "StockSummary_List")) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.stocksummary_petty, viewGroup, false);
}else if(positionvalue.equals( "CommonCustomer")){
view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.customersearch_petty,viewGroup,false);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(SearchAdapter.ViewHolder viewHolder, int i) {
if(positionvalue.equals( "StockSummary_List")) {
viewHolder.itemCodeStock.setText(mFilteredList.get(i).getItemCodeStock());
viewHolder.itemNameStock.setText(mFilteredList.get(i).getItemNameStock());
viewHolder.issuedStock.setText("Iss :" + mFilteredList.get(i).getIssuedStock() + mFilteredList.get(i).getUmoStock());
viewHolder.recievedStock.setText("Rec :" + mFilteredList.get(i).getRecievedStock() + mFilteredList.get(i).getUmoStock());
viewHolder.closingStock.setText("Clo :" + mFilteredList.get(i).getClosingStock() + mFilteredList.get(i).getUmoStock());
// viewHolder.umoStock.setText(mFilteredList.get(i).getUmoStock());
}else if(positionvalue.equals( "CommonCustomer")){
viewHolder.custName_commonCustdetail.setText(mFilteredList.get(i).getValueNameCustomer());
}
}
#Override
public int getItemCount() {
return mFilteredList.size();
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = mArrayList;
} else {
ArrayList<CommonSetterANDGetter> filteredList = new ArrayList<>();
for (CommonSetterANDGetter commonsetget : mArrayList) {
if (positionvalue.equals("StockSummary_List")) {
if (commonsetget.getItemCodeStock().toLowerCase().contains(charString) || commonsetget.getItemNameStock().toLowerCase().contains(charString)) {
filteredList.add(commonsetget);
}
}else if(positionvalue.equals( "CommonCustomer")){
if (commonsetget.getValueNameCustomer().toLowerCase().contains(charString)) {
filteredList.add(commonsetget);
}
}
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilteredList = (ArrayList<CommonSetterANDGetter>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView itemCodeStock, itemNameStock, issuedStock, recievedStock, closingStock, umoStock;// stock Sum
TextView custName_commonCustdetail;// common detail cust
public ViewHolder(View view) {
super(view);
if(positionvalue.equals( "StockSummary_List")) {
itemCodeStock = (TextView) view.findViewById(R.id.itemcode_stocksum);
itemNameStock = (TextView) view.findViewById(R.id.itemname_stocksum);
issuedStock = (TextView) view.findViewById(R.id.issue_stocksum);
recievedStock = (TextView) view.findViewById(R.id.recieve_stocksum);
closingStock = (TextView) view.findViewById(R.id.closing_stocksum);
}else if(positionvalue.equals( "CommonCustomer")){
custName_commonCustdetail= (TextView) view.findViewById(R.id.commonname_customerdetail);
custName_commonCustdetail.setOnClickListener(this);
}
}
#Override
public void onClick(View v) {
itemclicklistener.recyclerViewListClicked(v, this.getAdapterPosition());
}
}
}

how to filter RecyclerView with searchview correctly?

hi all I have implemented SearchView inside RecyclerView but when I search character name it is not searching any name and I have followed this tutorial
below my adapter class where I have implemented recyclerview with
Filtarable
public class LeovegasAdapter extends RecyclerView.Adapter implements Filterable {
private List<Hero> heros;
private List<Hero> filtarableList;
public LeovegasAdapter(List<Hero> heros) {
this.heros = heros;
filtarableList = filtarableList;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.hero_list, parent, false);
return new CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
Hero hero = heros.get(position);
holder.heroId.setText(hero.getId());
holder.heroName.setText(hero.getName());
}
#Override
public int getItemCount() {
return heros.size();
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
filtarableList = heros;
} else {
ArrayList<Hero> filteredList = new ArrayList<>();
for (Hero hero : heros) {
if (hero.getId().toLowerCase().contains(charString) || hero.getName().toLowerCase().contains(charString)) {
filteredList.add(hero);
}
}
filtarableList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filtarableList;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filtarableList = (List<Hero>) results.values;
notifyDataSetChanged();
}
};
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView heroId, heroName;
public CustomViewHolder(View view) {
super(view);
heroId = (TextView) view.findViewById(R.id.heroId);
heroName = (TextView) view.findViewById(R.id.heroName);
}
}
}
below my MainActivity.java
public class MainActivity extends AppCompatActivity {
public LeovegasAdapter leovegasAdapter;
public static final String publicKey = "4089ee37331d8211b080b047c58f6970";
public static final String privateKey = "18ccbcb58fdd12c22821f8b633a06f2b433d16c3";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LeoVegasInterface leoVegasInterface = LeoVegasClient.getApiService();
String ts = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
String hash = Hasher.md5(ts + privateKey + publicKey);
Call<LeoVegas> callHeroes = leoVegasInterface.getHeroes(ts, publicKey, hash);
callHeroes.enqueue(new Callback<LeoVegas>() {
#Override
public void onResponse(Call<LeoVegas> call, Response<LeoVegas> response) {
LeoVegas leoVegas = response.body();
Data data = leoVegas.getData();
Hero[] heroes = data.getResults();
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
leovegasAdapter = new LeovegasAdapter(Arrays.asList(heroes));
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setAdapter(leovegasAdapter);
}
#Override
public void onFailure(Call<LeoVegas> call, Throwable t) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem search = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(search);
search(searchView);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
private void search(SearchView searchView) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
leovegasAdapter.getFilter().filter(newText);
return true;
}
});
}
}
Change your below code
Few changes
Clear the list
Use addAll to fill with the result
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
//Updated code
String charString = charSequence.toString();
ArrayList<Hero> filteredList = new ArrayList<>();
if (charString.isEmpty()) {
filteredList.addAll(filtarableList);
} else {
ArrayList<Hero> filteredList = new ArrayList<>();
for (Hero hero : heros) {
if (hero.getId().toLowerCase().contains(charString) || hero.getName().toLowerCase().contains(charString)) {
filteredList.add(hero);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
//Update code
heros.clear();
if (results == null)
heros.addAll(mFilterConversations);
else {
heros.addAll((List<Hero>) results.values);
}
notifyDataSetChanged();
}
};
}

How to get item position in viewholder when swipe with filtered text

I was able to get the value of the viewHolder.getAdapterPosition() but what Im after is when I search for items using Filter and tried to swipe the searched item it always gives me the position 0.
Example list:
0: Apple
1: Banana
2: Mango
3: Coconut
4: Peanut
I searched for peanut and it should be in the first item on the list but when I tried to swiped it always return 0 as apple.
Here is my code
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, final int direction) {
Log.e("ITEM ID", String.valueOf(viewHolder.viewHolder.getAdapterPosition());
adapters.notifyDataSetChanged();
}
Please see Adapter Class:
public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.MyViewHolder>{
private Context context;
private List<ProductObject> productList;
private double total;
private List<ProductObject> filteredItems;
private ProductsInterface productsInterface;
public interface ProductsInterface {
void productsInt(ProductObject position);
}
public void setProductsInterface(ProductsInterface productsInterfaceListener){
productsInterface = productsInterfaceListener;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
ImageView img_url;
TextView prod_desc, prod_uom, prod_price, prod_quantity;
public MyViewHolder(View itemView, final ProductsInterface listener) {
super(itemView);
prod_desc = (TextView) itemView.findViewById(R.id.card_product_name);
prod_uom = (TextView) itemView.findViewById(R.id.card_uom);
prod_price = (TextView) itemView.findViewById(R.id.card_price);
img_url = (ImageView) itemView.findViewById(R.id.card_imageView);
prod_quantity = (TextView) itemView.findViewById(R.id.prod_quantity);
//listener.productsInt(filteredItems.get(getAdapterPosition()));
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null) {
//productsInterface.productsInt();
int position = getAdapterPosition();
Log.e("ADAPTER", String.valueOf(position));
if(position != RecyclerView.NO_POSITION){
listener.productsInt(filteredItems.get(getAdapterPosition()));
//ProductObject clickedItems = filteredItems.get(position);
}
}
}
});
}
}
public ProductsAdapter (Context context, List<ProductObject> listItems){
this.context = context;
this.productList = listItems;
this.filteredItems = listItems;
}
#Override
public ProductsAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_card_view, parent, false);
return new MyViewHolder(view, productsInterface);
}
#Override
public void onBindViewHolder(ProductsAdapter.MyViewHolder holder, int position) {
final ProductObject objectModel = filteredItems.get(holder.getAdapterPosition());
holder.prod_desc.setText(objectModel.getProd_desc());
holder.prod_uom.setText(objectModel.getProd_stockCode());
holder.prod_price.setText(String.valueOf(objectModel.getProd_price()));
holder.prod_quantity.setText(String.valueOf(objectModel.getProd_quantity()));
//prod id add here
/* Glide.with(context)
.load(objectModel.getProd_image())
.into(holder.img_url);*/
Glide.with(context)
.load(R.drawable.logo)
.into(holder.img_url);
}
#Override
public int getItemCount() {
return filteredItems.size();
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()) {
filteredItems = productList;
} else {
final ArrayList<ProductObject> mFilteredList = new ArrayList<>();
for (final ProductObject listFilter : productList) {
if (listFilter.getProd_desc().toLowerCase().contains(charString) ||
listFilter.getProd_stockCode().toLowerCase().contains(charString)
) {
mFilteredList.add(listFilter);
}
}
filteredItems = mFilteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredItems;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredItems = (ArrayList<ProductObject>) results.values;
notifyDataSetChanged();
}
};
}
}
Modify publishResults method to below
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredItems.clear();
filteredItems.addAll((ArrayList<ProductObject>) results.values);
notifyDataSetChanged();
}

Realm crashing when ItemFilter is Used in the Adapter [duplicate]

I'm using well RealmRecyclerViewAdapter. My problem is to implement a Filterable that not works. This is the code:
private class AirportAdapter extends RealmRecyclerViewAdapter<AirportR,RecyclerView.ViewHolder> implements Filterable
{
Context context;
OrderedRealmCollection<AirportR>listAirports;
public AirportAdapter(Context activity, OrderedRealmCollection<AirportR>airports)
{
super(activity,airports, true);
this.context = activity;
this.listAirports = airports;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.airport_show, parent,false);
AirportClass holder = new AirportClass(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
AirportR airportR = listAirports.get(position);
AirportClass mHolder = (AirportClass)holder;
mHolder.country.setText(airportR.getIsoCountry());
mHolder.name.setText(airportR.getName());
}
public Filter getFilter()
{
AirportFilter filter = new AirportFilter(this, listAirports);
return filter;
}
private class AirportFilter extends Filter
{
private final AirportAdapter adapter;
OrderedRealmCollection<AirportR>originalList;
OrderedRealmCollection<AirportR>filteredList;
private AirportFilter(AirportAdapter adapter, OrderedRealmCollection<AirportR> originalList)
{
super();
this.adapter = adapter;
this.originalList = originalList;
}
#Override
protected FilterResults performFiltering(CharSequence constraint)
{
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint.length() == 0)
{
filteredList.addAll(originalList);
}
else
{
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final AirportR airportR : originalList)
{
if (airportR.getName().toLowerCase().contains(filterPattern))
{
filteredList.add(airportR);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
adapter.listAirports.addAll((OrderedRealmCollection<AirportR>) results.values);
adapter.notifyDataSetChanged();
}
}
private class AirportClass extends RecyclerView.ViewHolder
{
TextView name, country;
ImageView image;
public AirportClass(View itemView)
{
super(itemView);
name = (TextView)itemView.findViewById(R.id.name);
country = (TextView)itemView.findViewById(R.id.country);
image = (ImageView)itemView.findViewById(R.id.imageView);
}
}
}
and I give back the error:
java.lang.UnsupportedOperationException: This method is not supported by RealmResults.
at io.realm.RealmResults.addAll(RealmResults.java:710)
at com.example.matteo.downloadairports.fragment.ListAirportFragment$AirportAdapter$AirportFilter.publishResults
how could I save the result after I filter it and update the adapter?
Thanks
Move the filtering to publishResults and use the UI thread Realm's queries to evaluate the new results.
private class AirportAdapter
extends RealmRecyclerViewAdapter<AirportR, RecyclerView.ViewHolder>
implements Filterable {
Realm realm;
public AirportAdapter(Context context, Realm realm, OrderedRealmCollection<AirportR> airports) {
super(context, airports, true);
this.realm = realm;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.airport_show, parent, false);
AirportClass holder = new AirportClass(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
AirportR airportR = getData().get(position);
AirportClass mHolder = (AirportClass) holder;
mHolder.bind(airportR);
}
public void filterResults(String text) {
text = text == null ? null : text.toLowerCase().trim();
RealmQuery<AirportR> query = realm.where(AirportR.class);
if(!(text == null || "".equals(text))) {
query.contains("fieldToQueryBy", text, Case.INSENSITIVE) // TODO: change field
}
updateData(query.findAllAsync());
}
public Filter getFilter() {
AirportFilter filter = new AirportFilter(this);
return filter;
}
private class AirportFilter
extends Filter {
private final AirportAdapter adapter;
private AirportFilter(AirportAdapter adapter) {
super();
this.adapter = adapter;
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
return new FilterResults();
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filterResults(constraint.toString());
}
}
private class AirportClass
extends RecyclerView.ViewHolder {
TextView name, country;
ImageView image;
public AirportClass(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
country = (TextView) itemView.findViewById(R.id.country);
image = (ImageView) itemView.findViewById(R.id.imageView);
}
public void bind(AirportR airportR) {
country.setText(airportR.getIsoCountry());
name.setText(airportR.getName());
}
}
}
in your adapter add this it may help you
fun filterResults(text: String?, realm: Realm) {
var text = text
text = text?.toLowerCase()?.trim { it <= ' ' }
val query = realm.where(YourObject::class.java)
if (!(text == null || "" == text)) {
query.contains("username", text, Case.INSENSITIVE).or().contains("username2", text, Case.INSENSITIVE)
}
updateData(query.findAllAsync()) // or findAll()
}

Add a search filter on RecyclerView with Cards?

I found solutions for filters on ListView and SearchView on RecyclerView separately, but I wish to combine them. Is it even possible?
Yes it is possible Your RecyclerView.Adapter can implement Filterable. After that you have to override Filter getFilter() method.
You have to define your own filter as is shown in the code below:
#Override
public Filter getFilter() {
return new YourFilterClass();
}
YourFilterClass
class YourFilterClass extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
//Here you have to implement filtering way
final FilterResults results = new FilterResults();
//logic to filtering
results.values = ...
results.count = ...
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// here you can use result - (f.e. set in in adapter list)
}
}
Example
public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.ViewHolder> implements Filterable {
private final List<User> userList;
private final List<User> filteredUserList;
private UserFilter userFilter;
public UserListAdapter(Context context) {
this.userList =new ArrayList<>();
this.filteredUserList = new ArrayList<>();
}
///... other methods
#Override
public Filter getFilter() {
if(userFilter == null)
userFilter = new UserFilter(this, userList);
return userFilter;
}
private static class UserFilter extends Filter {
private final UserListAdapter adapter;
private final List<User> originalList;
private final List<User> filteredList;
private UserFilter(UserListAdapter adapter, List<User> originalList) {
super();
this.adapter = adapter;
this.originalList = new LinkedList<>(originalList);
this.filteredList = new ArrayList<>();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint.length() == 0) {
filteredList.addAll(originalList);
} else {
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final User user : originalList) {
if (user.getName().contains(filterPattern)) {
filteredList.add(user);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filteredUserList.clear();
adapter.filteredUserList.addAll((ArrayList<User>) results.values);
adapter.notifyDataSetChanged();
}
}
}
After that in the place when you want to filtering call:
userListAdapter.getFilter().filter(text)
Here is complete sample code
Model Class
public class Skills {
int id;
String skill;
boolean isSelected;
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
Adapter Class
private static final String TAG = SkillAdapter.class.getSimpleName();
protected List<Skills> mOriginalData = new ArrayList<>();
protected List<Skills> mResultData = new ArrayList<>();
protected Activity mActivity;
OnRecyclerViewClick onRecyclerViewClick;
private ItemFilter mFilter = new ItemFilter();
public SkillAdapter(Activity activity, OnRecyclerViewClick onRecyclerViewClick) {
mActivity = activity;
this.onRecyclerViewClick = onRecyclerViewClick;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_skill,
parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Skills data = mResultData.get(position);
try {
final ViewHolder viewHolder = (ViewHolder) holder;
if (data != null) {
viewHolder.checkSkill.setText(data.getSkill());
viewHolder.checkSkill.setChecked(data.isSelected());
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return mResultData.size();
}
public void addItem(Skills exam) {
mOriginalData.add(exam);
mResultData.add(exam);
int index = mOriginalData.indexOf(exam);
notifyItemInserted(index);
}
public void removeItem(int index) {
mOriginalData.remove(index);
notifyItemRemoved(index);
}
public void removeItem(Skills exam) {
int index = mOriginalData.indexOf(exam);
mOriginalData.remove(exam);
notifyItemRemoved(index);
}
public Filter getFilter() {
return mFilter;
}
public Skills getItem(int index) {
return mOriginalData.get(index);
}
public void replaceItem(int index, Skills audioMeta) {
mOriginalData.set(index, audioMeta);
notifyItemChanged(index);
}
public class ViewHolder extends RecyclerView.ViewHolder {
CheckBox checkSkill;
public ViewHolder(View itemView) {
super(itemView);
checkSkill = (CheckBox) itemView.findViewById(R.id.chkSkill);
checkSkill.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onRecyclerViewClick.onItemClick(v, getLayoutPosition());
}
});
}
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
int count = mOriginalData.size();
final ArrayList<Skills> tempFilterList = new ArrayList<Skills>(count);
String filterableString;
for (int i = 0; i < count; i++) {
filterableString = mOriginalData.get(i).getSkill();
if (filterableString.toLowerCase().contains(filterString)) {
tempFilterList.add(mOriginalData.get(i));
}
}
results.values = tempFilterList;
results.count = tempFilterList.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mResultData.clear();
mResultData = (ArrayList<Skills>) results.values;
notifyDataSetChanged();
}
}
In Activity Use
mAdapter = new SkillAdapter(SkillsActivity.this, SkillsActivity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
recyclerView.setAdapter(mAdapter);
Then Filter
editSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
mAdapter.getFilter().filter(editSearch.getText().toString());
}
});
Inside Fragment Class declare that:
protected List<User> mDataset;
protected List<User> mDataOrigin;
then inside onCreate add same source destination to both dataSet ant dataOrigin
mDataset = getObjectsFromDB();
mDataOrigin = getObjectsFromDB();
Finally use the magic function:
private void filterRecyclerView(String charText){
charText = charText.toLowerCase();
clearDataSet();
if (charText.length() == 0) {
mDataset.addAll(mDataOrigin);
} else {
for (User user : mDataOrigin) {
if (user.getName().toLowerCase().contains(charText)) {
mDataset.add(user);
}
}
}
mAdapter.notifyDataSetChanged();
}
Notice User is the list content you can replace with your Object have fun :)

Categories

Resources