This is filter method of my recyclerview filterable code.
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mParentItemList = mOriginalList;
} else {
List<ParentListItem> filteredList = new ArrayList<>();
for (ParentListItem row : mParentItemList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
for (Object childListItem : row.getChildItemList()) {
if (((Help) childListItem).getName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(row);
}
}
// if (row.getName().toLowerCase().contains(charString.toLowerCase()) || row.getPhone().contains(charSequence)) {
// filteredList.add(row);
// }
}
mParentItemList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mParentItemList;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mParentItemList = (ArrayList<ParentListItem>) filterResults.values;
notifyDataSetChanged();
}
};
}
I am getting filtered list in mParentList variable properly but when i am calling notifydatasetchanged() recyclerview not updating and UI is not updating.
Related
I am trying to search a RecylerView with EditText, i follow some tutorial and i get Error NullPointerException. my RecyclerView is working good , but my search program is not working.
this is my Adapter Code
public class ListDefoodAdapter extends RecyclerView.Adapter<ListDefoodAdapter.CategoryViewHolder> implements Filterable {
private Context context;
private ArrayList<DefoodListData> listDefood;
private ArrayList<DefoodListData> listFilter;
public ListDefoodAdapter(Context context) {
this.context = context;
}
public ArrayList<DefoodListData> getListDefood() {
return listDefood;
}
public void setListDefood(ArrayList<DefoodListData> listDefood) {
this.listDefood = listDefood;
}
#NonNull
#Override
public CategoryViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemRow = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_transaksidefood, viewGroup, false);
return new CategoryViewHolder(itemRow);
}
public Filter getFilter(){
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()){
listDefood = listFilter;
} else {
ArrayList<DefoodListData> filteredList = new ArrayList<>();
for (DefoodListData row : listFilter){
String id = String.valueOf(row.getId());
if (id.toLowerCase().contains(charString.toLowerCase()) ||
row.getNamaUser().toLowerCase().contains(charString.toLowerCase()) ||
row.getNamaDriver().toLowerCase().contains(charString.toLowerCase())){
filteredList.add(row);
}
}
listDefood = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = listDefood;
return filterResults;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
listDefood = (ArrayList<DefoodListData>) results.values;
notifyDataSetChanged();
}
};
}
#Override
public int getItemCount() {
return getListDefood().size();
}
}
and this is my code in fragment
private void searchData(){
btn_search.setOnClickListener(v -> {
String keySearch = edt_cari.getText().toString();
listDefoodAdapter.getFilter().filter(keySearch);
});
}
but i get error null on method getItemCount(). Please help me to solve this problem
there is an issue in your data assign in listFilter.
you are adding data in listDefood in below method
public void setListDefood(ArrayList<DefoodListData> listDefood) {
this.listDefood = listDefood;
}
but you are not adding a list in listFilter.
You need to add list in Both array.
public void setListDefood(ArrayList<DefoodListData> listDefood) {
this.listDefood = listDefood;
this.listFilter = listDefood;
}
Assign filtered list size to filter result.
try with this
public void setListDefood(ArrayList<DefoodListData> listDefood) {
this.listDefood = listDefood;
this.listFilter = listDefood;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
listDefood = (List<DefoodListData >) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
ArrayList<DefoodListData> filteredList = new ArrayList<>();
for (DefoodListData row : listFilter) {
if (String.valueOf(row.getId().toLowerCase().trim().contains(charString)) ||
row.getNamaUser().toLowerCase().trim().contains(charString) ||
row.getNamaDriver().toLowerCase().trim().contains(charString)) {
filteredList.add(row);
}
}
results.count = filteredList.size();
results.values = filteredList;
return results;
}
};
}
I want to make a searchView like this image below. The searchView is received data from local database then it filters data like AutoCompleteTextView.
How can i make it?
Here is image:
enter image description here
I use RecyclerView for list display item, and in Adapter I implements a Filterable:
private List<Bank> banksList;
private List<Bank> bankListFiltered;
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()) {
bankListFiltered = banksList;
} else {
List<Bank> filteredList = new ArrayList<>();
for (Bank row : banksList) {
String shortName = row.getShortName().toLowerCase();
if (shortName.contains(charString)) {
filteredList.add(row);
}
}
bankListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = bankListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
bankListFiltered = (ArrayList<Bank>) results.values;
notifyDataSetChanged();
}
};
}
#Override
public int getItemCount() {
return bankListFiltered.size();
}
public BanksAdapter(List<Bank> banksList) {
this.banksList = banksList;
this.bankListFiltered = banksList;
}
And in my activity, add event for SearchView:
new SearchView(this).setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
banksAdapter.getFilter().filter(newText);
return true;
}
});
I have an app which contains recyclerview with searchview on long press item is working fine in case of a normal list, But when I type anything using searchview it comes on the top but when I click on that item I am always getting an item from the normal list at position 0.How do I resolve this issue.
code:-
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()) {
mFilterList = models;
} else {
ArrayList<UserListingModel> filteredList = new ArrayList<>();
for (UserListingModel userListingModel : models) {
if (userListingModel.getUseName().toLowerCase().contains(charString.toLowerCase()) || userListingModel.getUseName().toUpperCase().contains(charString.toUpperCase())) {
filteredList.add(userListingModel);
}
}
mFilterList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilterList;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mFilterList = (ArrayList<UserListingModel>) results.values;
notifyDataSetChanged();
}
};
}
searchview code:-
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
Log.e(TAG, "Position");
Users.mAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
Users.mAdapter.getFilter().filter(newText);
return false;
}
});
I use the recyclerview filter
I want to show the ordering of the data on a more similar basis, not on the basis of id
For example
When I search the tree, the order is displayed like this
Data with id 1 - big tree
Data with id 2 - tree
While it's better to show this
1-tree
2-big tree
My filter method
Should I make some changes here?
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
ArrayList<Tabir> filterList = new ArrayList<>();
for (Tabir tabir : mArrayList) {
if (tabir.getTitle().toLowerCase().contains(charString)) {
filterList.add(tabir);
}
}
mFilteredList = filterList;
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
notifyDataSetChanged();
Log.e(MainActivity.TAG, "results=" + results);
}
};
}
I am using a autocompletetextview with custom adapter in android. it works fine. But when i click backspace to clear selected item from autocomplete textview it freezes, or there is a delay in deleting. How can i overcome this ? My filter codes are given below
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
suggestions.clear();
FilterResults filterResults = new FilterResults();
for (Names people : tempItems) {
if(people.getName().toLowerCase().contains(constraint.toString()
.toLowerCase())) {
suggestions.add(people);
}
}
// FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults
results) {
List<Names> filterList = (ArrayList<Names>) results.values;
if (results != null && results.count > 0) {
clear();
for (Names people : filterList) {
add(people);
notifyDataSetChanged();
}
}
}
};
What am i doing wrong ? Thanks in Advance.
Modify you filter according to the below code. You are notifying the adapter inside the loop, it should be notified once the whole list is added into the other list i.e. outside the loop.
// This is my whole adapter and works like a charm and about the updation on the UI thread, yes I am notifying the adapter on the UI thread.
public class SuburbSuggestionsAdapter extends ArrayAdapter<String> implements Filterable {
protected static final String TAG = "SuggestionAdapter";
private List<String> suggestions;
private Context context;
private List<String> SuburbList = new ArrayList<>();
public SuburbSuggestionsAdapter(Context context) {
super(context, android.R.layout.simple_dropdown_item_1line);
suggestions = new ArrayList<String>();
this.context = context;
}
#Override
public int getCount() {
return (null != suggestions ? suggestions.size() : 0);
}
#Override
public String getItem(int index) {
return suggestions.get(index);
}
#Override
public Filter getFilter() {
Filter myFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(!TextUtils.isEmpty(constraint)){
WebServiceHandler.hitFetchSuburbList(context, constraint.toString(), new CallbackRest() {
#Override
public void onDone(String response) {
if(SuburbList.size()!=0){
SuburbList.clear();
}
try {
JSONArray jsonArray = new JSONArray(response);
for(int i=0; i<jsonArray.length(); i++){
SuburbList.add(jsonArray.get(i).toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
// A class that queries a web API, parses the data and
// returns an ArrayList<GoEuroGetSet>
List<String> new_suggestions = SuburbList;
suggestions.clear();
for (int i=0;i<new_suggestions.size();i++) {
suggestions.add(new_suggestions.get(i));
}
// Now assign the values and count to the FilterResults
filterResults.values = suggestions;
filterResults.count = suggestions.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence contraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
return myFilter;
}
}