Title: app crashes on notifyDataSetChanged() Using Filter
Tags: android;listview;android-listview;android-spinner
Question: i have ListView that contains spinner, an image and a TextView. Above this ListView I have an EditText where a user can type his required item name and all the related items has been shown in the ListView. My code is working till here but the problem is when i try to delete the last character the app just gone crashed. I think the listview is not refreshed properly. I have searched many answers but found nothing that relates to my problem so plz help me in that app carsh problem.
Here is my code of getFilter in LazyAdapter that extends from BaseAdapter
@SuppressLint("DefaultLocale")
public android.widget.Filter getFilter() {
return new android.widget.Filter() {
@SuppressLint("DefaultLocale")
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults Result = new FilterResults();
// if constraint is empty return the original names
if (TextUtils.isEmpty(constraint)){
//Result.values = storedata;
Result.count = listDetails.size();
return Result;
}
ArrayList<items&gt; Filtered_Names = new ArrayList<items&gt;();
String filterString = constraint.toString().toLowerCase();
String filterableString;
for(int i = 0; i<listDetails.size(); i++){
items searchdata = listDetails.get(i);
String title = searchdata.title();
String id = searchdata.id();
String imageUrl = searchdata.imageUrl();
String pprice = searchdata.pprice();
String shippingPrice = searchdata.shippingPrice();
String stock = searchdata.stock();
filterableString = title+" "+id+" "+imageUrl+" "+pprice+" "+shippingPrice+" "+status+" "+stitle+" "+stock+"
if(filterableString.toLowerCase().contains(filterString)){
Filtered_Names.add(listDetails.get(i));
//Log.e("Added", String.valueOf(Filtered_Names.size()));
}
}
Result.values = Filtered_Names;
Result.count = Filtered_Names.size();
//Log.e("Results", Result.values.toString() + String.valueOf(Result.count));
return Result;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// TODO Auto-generated method stub
@SuppressWarnings("unchecked")
ArrayList<items&gt; resultList =(ArrayList<items&gt;) results.values;
LazyAdapter.this.listDetails = resultList;
LazyAdapter.this.notifyDataSetChanged();
}
};
and here is the code in the Activity
inputSearch = (EditText) findViewById(R.id.inputsearch);
if(adapter!=null){
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
try{
ItemsActivity.this.adapter.getFilter().filter(cs.toString());
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
And here is what logcat says
FATAL EXCEPTION: main
strongdanny@example.com(LazyAdapter.java:48)
at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:778)
at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:31)
at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
at com.example.itemspac.LazyAdapter$3.publishResults(LazyAdapterGifts.java:305)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
And here is my getCount() Method
@Override
public int getCount() {
// TODO Auto-generated method stub
return listDetails.size();
Comment: @peshkira you mean after the getFilter called the listDetails gone null? while at first the view is created successfully.

Comment: Yes you are right but i am wonder that why getCount() at first not returns null when the view is successfully created and it happens after the getFilter() call.

Comment: this is my Constructor `public  LazyAdapter(Context context , ArrayList list)
this.context = context;
listDetails = list;
downloader = new ImageDownloader();

Comment: listDetails is obviously null when the getCount() method gets called. Maybe change to ```return listDetails == null ? 0 : listDetails.size();```

Comment: I cannot be sure, but I assume in your ```publishResults``` the ArrayList you set to the LazyAdapter is null. Maybe add a check there to verify that.

Comment: My guess again - in your LazyAdapter, somewhere in the constructor you have something like - ```ArrayList listDetails = new ArrayList();```

Here is the accepted answer: You probably initialise your ArrayList somewhere and then the first call(s) to getCount() return the correct result. Afterwards you publish new Results and you set the array to null, because you don't check.
This causes the getCount() to throw a NullPointerException.
The easy fix will be to change the getCount() method to something like:
public int getCount() {
return listDetails == null ? 0 : listDetails.size();
Better yet is to do a null check in the publishResults method and to handle the initialisation of the adaptor fields accordingly.
Edit: From the comments above you say that your constructor accepts an ArrayList as a parameter. So somewhere in your code you must initialise your LazyAdapter with something like:
new LazyAdapter(context, new ArrayList())
This inits the listDetails ArrayList and you don't get a strongdanny@example.com.
Comment for this answer: after what you have said i did and the app don't get close but the list view is empty after text enter in the search box. The logcat now says `com.example.itemspac.LazyAdapter.(LazyAdapter.java:36)
at com.example.itemspac.LazyAdapter.(LazyAdapter.java:41)` and line 36 is the constructor first line.
Comment for this answer: this is the line 36 `public LazyAdapter(Context context , ArrayList list)` and 41 is imagedownloader
Comment for this answer: Yes man this is the answer but tell me where should i initialize this line new `LazyAdapter(context, new ArrayList())` to avoid the null filter?
Comment for this answer: answer me of that second question i will accept both. this is the  [link](http://stackoverflow.com/questions/21854534/android-filter-returns-an-empty-null-array-list)
Comment for this answer: this seems to be the correct behaviour. The app does not crash and your list view is empty because your filter returns an empty (null) array list. I believe this answers this question and if you have other questions, you should ask them separately.
Comment for this answer: You should initialze the adapter in the Activity where you have the list view and where you associate the adapter to the same list view. Is that what you mean?


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 6, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2014:00:02/18/14', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<android><listview><android-listview><android-spinner>', 'Title': 'app crashes on notifyDataSetChanged() Using Filter', 'ViewCount': 2710, 'id': 21850769, 'user_AboutMe': '<p>Java and Android Developer.</p>\n', 'user_AccountId': 3996753.0, 'user_DisplayName': 'Abid Khan', 'user_Reputation': 2391.0, 'user_Views': 255.0, 'user_id': 3294034.0}}