Andoxko Andoxko - 2 months ago 25
Android Question

notifyDataSetChanged not working

My app uses a

MultiColumnListView
(https://github.com/huewu/PinterestLikeAdapterView) and as its name says it helps creating multi column list views.

The library is great, but as they specify, filtering is not supported.

So I am trying to create my own text-filter functionality with a simple edit text.

Finally I achieve to filter the list but now I need to refresh the listView and recall the setAdapter because I pass the list on it.

MyAdapter adapter = new MyAdapter(this,myList);
listView.setAdapter(adapter);


When I execute
listView.invalidateViews()
or
adapter.notifyDataSetChanged()
the listView is refreshed but with the old list.

Which is the best way of recalling the setAdapter? or maybe is another way of doing this..

Thanks in advance

EDIT:

//Method that filters the list
Log.i("On filter myList.size()",""+myList.size());
adapter.notifyDataSetChanged();

//on the Adapter
Log.i("On Adapter myList.size()",""+myList.size());


Log:

enter image description here

Adapter Class:

public class MiAdaptadorListaComercios extends BaseAdapter{

//Textview and Imageviews declarations

private Context contexto;

private List<Comercio> myList;

public MiAdaptadorListaComercios(Context c,List<Comercio> myList){
this.contexto = c;
this.myList = new ArrayList<Comercio>();
this.myList = myList;
}
@Override
public int getCount() {
Log.i("On Adapter myList.size()",""+listaComercios.size());
return myList.size();
}

@Override
public Object getItem(int position) {
return myList.get(position);
}

@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view =null;

if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) contexto.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_cell, null);
}
else{
view = convertView;
}

//set views Texteviews text,font etc...

return view;
}


}

Activity Class:

public class ListaComercio extends Activity {

private MultiColumnListView mAdapterView = null;
EditText searchBar;
private ArrayList<Comercio> myList;
private ArrayList<Comercio> filteredList;
MyAdapter adapter;


public ListaComercio(){
myList = new ArrayList<Comercio>();
filteredList = new ArrayList<Comercio>();
}

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.lista_comercios);

mAdapterView = (MultiColumnListView) findViewById(R.id.list);

adapter = new MyAdapter(ListaComercio.this,myList);

mAdapterView.setAdapter(adapter);


searchBar.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
CharSequence filer = v.getText();

for(Comercio co : myList)
{
if(co.getName().contains(filer))
{
filteredList.add(co);
}
}

myList = filteredList;

Log.i("On filter myList.size()",""+myList.size());

myList.clear();
adapter.notifyDataSetChanged();
//mAdapterView.invalidateViews();

return true;
}
return false;
}
});
}
}

Answer

just change your myList and call adapter.notifyDataSetChanged() don't set a new adapter each time.

In the constructor of your custom adapter do call super that takes ArrayList as the argument.

call this:

public MiAdaptadorListaComercios(Context c,List<Comercio> myList){
    super(c,0,myList);
    this.contexto = c;
    this.myList = myList;
}

You can keep the adapter as it is the problem is in this line:

myList = filteredList;

instead of changing the reference you should change the list itself.

myList.clear();
myList.addAll(filteredList);

By doing this you will loose your original list to I would suggest keeping another list call ed originalList which will have the complete list and initialize myList in onCreate by:

myList=new ArrayList(originalList);

so every time you want to re-set just call:

myList.clear();
myList.addAll(originalList);    

and in

    for(Comercio co : originalList)
            {
                if(co.getName().contains(filer))
                {
                    filteredList.add(co);
                }
            }