I have a search bar for a list of players. When they user types in the search bar it filters the list. Noticed that when the device rotates it crashes. The logic for the search view is carried out in a separate adapter. Is there a way to amend the code so that it does not crash on rotate? The error i get is
Attempt to invoke virtual method 'android.widget.Filter com.example.android.prototype2.views.PlayerListAdapter.getFilter()' on a null object reference
//Assign the search view variable
searchView = findViewById(R.id.search_users);
//Set onQueryListener for when text is entered into the search bar
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
//When text is changed filter the results from the playerlist adapter
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
The adapter logic is in the playerlistAdapter
private Filter exampleFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<UserHelperClass> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(playerListFull);
} else {
//trim -empty spaces removed
String filterPattern = constraint.toString().toLowerCase().trim();
for (UserHelperClass player : playerListFull) {
if (player.getName().toLowerCase().contains(filterPattern)) {
filteredList.add(player);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
playersList.clear();
playersList.addAll((List) results.values);
notifyDataSetChanged();
}
};
I managed to get it working by adding if (adapter != null), before adapter.getFilter().filter(newText);
Related
I am having trouble with Setting previous results back in recyclerView when a text is deleted from searchView's Filter box. I use the following code in the adapter which filters the data finely. But the thing is it does not set the previous values in the recyclerView when the search text is deleted from the search view.
recyclerView adapter's get filter method
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
results = names;
} else {
ArrayList<tab> filteredList = new ArrayList<>();
for (tab row : names) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getName().toLowerCase().contains(charString.toLowerCase()) || row.getmsg().contains(charSequence)) {
filteredList.add(row);
}
}
results = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = results;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
names = (ArrayList<tab>) filterResults.values;
// refresh the list with filtered data
notifyDataSetChanged();
}
};
}
Main activity code
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
// listening to search query text change
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// filter recycler view when query submitted
gtxx.getFilter().filter(query);
// gtxx.notifyDataSetChanged();
return false;
}
#Override
public boolean onQueryTextChange(String query) {
// filter recycler view when text is changed
gtxx.getFilter().filter(query);
//gtxx.notifyDataSetChanged();
return false;
}
});
return true;
}
Setting value in the adapter
gtxx = new listadapttor(con_list);
recyclerView.setAdapter(gtxx);
In your adapter create two list, with the same data. Let say second list is temporary list. Set adapter using that list and do filtering on the second list from first list. Refer the code below:
private List<YourObject> tempList;
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
//this is the main list, which contains filtered items
//and tempList always contains original data.
//so when empty text is passed to filterable it will reset
//the list using original data from tempList
mainList = (List<YourObject>) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
List<YourObject> filteredItems = new ArrayList<YourObject>();
for (int i = 0; i < tempList.size(); i++) {
YourObject data = tempList.get(i);
if ((data.getName() != null && data.getName().toLowerCase().contains(constraint.toString().toLowerCase()))) { //Your filtering code here
filteredItems.add(data);
}
}
results.count = filteredItems.size();
results.values = filteredItems;
}
else
{
synchronized (this) {
results.values = tempList;
results.count = tempList.size();
}
}
return results;
}
};
return filter;
}
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 am been trying to figure what seems to be the issue, but can get my head round it, basically i am filtering my listview which uses custom adapter that has images and text. its works first time e.g. when the activity runs for the first time it has all the data and when i type something in the search box it filters it. but then from there if i now enter something else it doesn print anything and the array is empty which hold the data. any suggestion would be appreciated.
filter code fragment
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
data= (List<Data>) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<Item> FilteredArrayNames = new ArrayList<Item>();
// perform your search here using the searchConstraint String.
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < data.size(); i++) {
Item dataNames = data.get(i);
if (dataNames.title.toLowerCase().contains(constraint.toString())) {
FilteredArrayNames.add(dataNames);
}
}
results.count = FilteredArrayNames.size();
results.values = FilteredArrayNames;
Log.e("VALUES", results.values.toString());
return results;
}
};
return filter;
}
activity code fragment
text =(SearchView)findViewById(R.id.searchData);
text.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText.toString());
return true;
}
});
try returning false in onQueryTextChange() method.
As on the picture linked below, there is a dark textbox on the center of the screen as user enter the text on searchView. How to get rid of that?
Search related code in my MainActivity.java
listView.setTextFilterEnabled(true);
searchview = (SearchView) findViewById(R.id.searchView);
searchview.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText)
{
if (TextUtils.isEmpty(newText)) {
listView.clearTextFilter();
} else {
listView.setFilterText(newText);
}
return false;
}
#Override
public boolean onQueryTextSubmit(String query)
{
return false;
}
});
Search related code on my MyAdapter.java
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<DrugItem> results = new ArrayList<DrugItem>();
if (filteredItemsArrayList == null)
filteredItemsArrayList = itemsArrayList;
if (constraint != null) {
if (itemsArrayList != null && filteredItemsArrayList.size() > 0) {
for (final DrugItem g : filteredItemsArrayList) {
if (g.getDrugGenericName().toLowerCase()
.contains(constraint.toString()) || g.getDrugBrandName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
itemsArrayList = (ArrayList<DrugItem>) results.values;
notifyDataSetChanged();
}
};
}
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
Search related code in my activity_main.xml
<SearchView
android:iconifiedByDefault="false"
android:layout_below="#+id/toprow"
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Enter Drug Name To Filter......." />
How do I remove popup text from listview filter?
i Searched this was answered before as the link above. There is no solution. Use other way to do filtering instead of setTextFilterEnabled(true)
I am trying to search in list view in android. here is my code
#Override
public Filter getFilter(){
return new Filter(){
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
constraint = constraint.toString();
List<FoodCell> founded = new ArrayList<FoodCell>();
for(FoodCell item: allItemFood){
if(item.cellText.toString().contains(constraint)){
founded.add(item);
}
}
result.values = founded;
result.count = founded.size();
}else
result.count = 0;
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
if(results.count != 0){
for (FoodCell item : (List<FoodCell>) results.values) {
add(item);
}
}
notifyDataSetChanged();
}
};
}
#Override
public boolean onQueryTextChange(String newText) {
//check if user deleted a character
if(length > newText.length()){
allItemFood = allItemFoodTmp;
}
if (TextUtils.isEmpty(newText)) {
adapter = new CustomListViewAdapter(this, R.layout.listfood,allItemFood);
getListView().setAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
} else {
adapter.getFilter().filter(newText);
}
length = newText.length();
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
assume that we have the following items in list , aa,ab,ac
when i enter text "aaz" as search query , it shows empty list which is true but when i delete character "z" from search query,the result remains empty which is false as a result expected.
how can i solve it ?
Not sure which widget you are using to take the search text input, if it is an EditView (considering which I am answering) then you should try adding a TextWatcher to it and then in the onTextChanged() method insert your search login which will execute it every time you add or remove a character inside the EditText.
Do let me know if you are using something else, and I will try to help accordingly. Happy coding. :)