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:
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;
}
});
}
}
From the docs notifyDataSetChanged() : Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
Use the notifyDataSetChanged() every time the list is updated. To call it on the UI-Thread, use the runOnUiThread() of Activity. Then, notifyDataSetChanged() will work.
What does notifyDataSetChanged() do on recyclerview ? Notify any registered observers that the data set has changed. There are two different classes of data change events, item changes and structural changes. Item changes are when a single item has its data updated but no positional changes have occurred.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With