8

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;
            }
        });
    }
    }
Victor Oliveira
  • 3,293
  • 7
  • 47
  • 77
Andoxko
  • 1,021
  • 2
  • 12
  • 19

2 Answers2

21

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);
                }
            }
vipul mittal
  • 17,343
  • 3
  • 41
  • 44
  • Thank you, for answering that fast, but that is what I am doing and it is not working. I have edited my question to specify that – Andoxko Feb 06 '14 at 09:36
  • share your MyAdapter class as well – vipul mittal Feb 06 '14 at 09:36
  • thanks again. But when I call `super()` on the constructor nothing changes and if I try to call `super(myList)` I get an error telling that I must remove the argument to match `BaseAdapter`. What am I doing wrong? – Andoxko Feb 06 '14 at 10:00
  • Thank you, but unfortunately I am getting this error on the eclipse [errorImage1](http://postimg.org/image/6fvh0isct/) [errorImage2](http://postimg.org/image/9ji3yw3mv/). Even though I have edited the question and I have added the `Activity` which sets the adapter and the list, maybe the error is there. Thank you so much again – Andoxko Feb 06 '14 at 11:20
  • extend with ArrayAdapter instead – vipul mittal Feb 06 '14 at 11:23
  • It works!! The problem was the List itself not the adapter. Thank You very much! You are a lifesaver!! :) – Andoxko Feb 06 '14 at 11:44
6

You need to clear older myList.clear() and then call adapter.notifyDataSetChanged()

Update:

Change your code like:

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

Also, do it like

myList.clear();
myList.addAll(originalList);   
M D
  • 47,665
  • 9
  • 93
  • 114
  • 1
    Thank you for your answer, but unfortunately it is not working.. I have edited my question and I've include more details. I hope that will hep you guessing what am I doing wrong – Andoxko Feb 06 '14 at 09:47
  • But when I do that the list is always empty... or should I add `this.myList = myList` after the new? – Andoxko Feb 06 '14 at 11:29