Cómo filtrar ListView utilizando getFilter () en BaseAdapter

En mi aplicación tengo crear una vista de lista personalizada y quiero implementar un filtro para que la lista se puede filtrar de acuerdo con el texto introducido en el EditText. Estoy utilizando un BaseAdapter como una clase separada y estoy llamando a esa clase en mi actividad principal. También he implementado el addTextChangedListener () en mi actividad principal y también he implementado el getFilter () en mi clase BaseAdapter. Pero no sé cómo puedo utilizar getFilter () y puedo filtrar mi lista en consecuencia. En la lista agrego los valores de una URL de JSON. Por favor, ayúdame a dejarme saber que cómo puedo utilizar el getFilter () para filtrar mi lista.

El código de la clase de actividad:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView)findViewById(R.id.listView1); et1 = (EditText)findViewById(R.id.editText1); inflator = getLayoutInflater(); et1.addTextChangedListener(this); JsonParser jParser = new JsonParser(); JSONObject json = jParser.getJSONfromUrl(url); try { JSONArray explore = json.getJSONArray("explore"); for(int i=0; i<explore.length(); i++) { JSONObject exp = explore.getJSONObject(i); list.add(exp.getString("username")); } } catch(JSONException e) { e.printStackTrace(); } srchadptr = new SearchAdapter(this, inflator, list); lv.setAdapter(srchadptr); } public void afterTextChanged(Editable s) { // TODO Auto-generated method stub srchadptr.getFilter().filter(s); } public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub } 

El código de la clase BaseAdapter:

 public class SearchAdapter extends BaseAdapter implements Filterable { Context context; LayoutInflater inflater; Button btn; View vw; ArrayList<String> list = new ArrayList<String>(); public SearchAdapter(Context context, LayoutInflater inflater, ArrayList<String> list) { // TODO Auto-generated constructor stub this.context = context; this.inflater = inflater; this.list = list; } /*public CharSequence filter(CharSequence cs) { return cs; }*/ public int getCount() { // TODO Auto-generated method stub return list.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return position; } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub LinearLayout ll = (LinearLayout) vw; final EditText edt = ((EditText)ll.getChildAt(0)); vw = inflater.inflate(R.layout.list_items, null); ImageView img = (ImageView)vw.findViewById(R.id.imageView1); TextView tv = (TextView)vw.findViewById(R.id.textView1); btn = (Button)vw.findViewById(R.id.button1); tv.setText(String.valueOf(list.get(position))); btn.setText(String.valueOf(list.get(position))); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(context, list.get(position), Toast.LENGTH_LONG).show(); } }); return vw; } public android.widget.Filter getFilter() { // TODO Auto-generated method stub return new android.widget.Filter() { @Override protected void publishResults(CharSequence constraint, FilterResults results) { // TODO Auto-generated method stub } @Override protected FilterResults performFiltering(CharSequence constraint) { // TODO Auto-generated method stub return null; } }; } } 

Gracias por adelantado…

Espero que este ejemplo pueda ayudarte

En la actividad Main_Activity

  EditText etSearch; BaseAdapterFilterable adapter; etSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // Listview name of the class Listview.this.adapter.getFilter().filter(s); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable s) { // TODO Auto-generated method stub } }); 

En su adaptador poner esta clase para usarlo en el método getfilter

 public class filter_here extends Filter{ @Override protected FilterResults performFiltering(CharSequence constraint) { // TODO Auto-generated method stub FilterResults Result = new FilterResults(); // if constraint is empty return the original names if(constraint.length() == 0 ){ Result.values = Original_Names; Result.count = Original_Names.size(); return Result; } ArrayList<String> Filtered_Names = new ArrayList<String>(); String filterString = constraint.toString().toLowerCase(); String filterableString; for(int i = 0; i<Original_Names.size(); i++){ filterableString = Original_Names.get(i); if(filterableString.toLowerCase().contains(filterString)){ Filtered_Names.add(filterableString); } } Result.values = Filtered_Names; Result.count = Filtered_Names.size(); return Result; } @Override protected void publishResults(CharSequence constraint,FilterResults results) { // TODO Auto-generated method stub Names = (ArrayList<String>) results.values; notifyDataSetChanged(); } } 

También en la instancia de retorno del adaptador de la clase filter_here

 @Override public Filter getFilter() { // TODO Auto-generated method stub return filter; } 

En su BaseAdapter, almacene dos copias de la lista, una original y otra filtrada. Y cambie todas las referencias en su BaseAdapter, para usar solamente la lista filtrada.

1) en su actividad, active el filtro en su ListView : lv.setTextFilterEnabled (true);

2) en su textWatcher, dispare el filtro en su listadapter srchadptr.getFilter (). Filter (s)

3) Actualice su baseadapter para almacenar dos copias de los datos y cambie las referencias para referirse a la lista filtrada en lugar de la lista original.

 public class SearchAdapter extends BaseAdapter implements Filterable { List<String> list = new ArrayList<String>(); List<String> listFiltered = new ArrayList<String>(); public SearchAdapter(Context context, ArrayList<String> list) { this.context = context; this.inflater = LayoutInflater.from(context) this.list = list; this.listFiltered=list; } public int getCount() { return listFiltered.size();//note the change } public Object getItem(int position) { return listFiltered.get(position);//note the change } //only altered lines shown in this function (change ``list`` to ``listFiltered``) public View getView(final int position, View convertView, ViewGroup parent) { tv.setText(String.valueOf(listFiltered.get(position))); btn.setText(String.valueOf(listFiltered.get(position))); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { Toast.makeText(context, listFiltered.get(position), Toast.LENGTH_LONG).show(); } }); } //now write your filter function @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); if (constraint == null || constraint.length() == 0) { //no constraint given, just return all the data. (no search) results.count = list.size(); results.values = list; } else {//do the search List<String> resultsData = new ArrayList<>(); String searchStr = constraint.toString().toUpperCase(); for (String s : list) if (s.toUpperCase().contains(searchStr)) resultsData.add(s); results.count = resultsData.size(); results.values = resultsData; } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { listFiltered = (ArrayList<String>) results.values; notifyDataSetChanged(); } }; } 

Me parece que el trabajo con filtros no todo lo que conveniente .. ¿Cómo lo hago es:

  ((EditText)findViewById(R.id.etSearch)).addTextChangedListener(new TextWatcher(){ private boolean mCountIncreased; @Override public void afterTextChanged(Editable s) { if (s.toString().length() == 0){ mDisplayedList.clear(); mDisplayedList.addAll(mFullList); mListAdapter.notifyDataSetChanged(); return; } if (mCountIncreased){ mDisplayedList.clear(); mDisplayedList.addAll(mFullList); } List<Item> toRemove = new ArrayList<Item>(); for (Item item : mDisplayedList){ if (someCondition) toRemove.add(currency); } } mDisplayedList.removeAll(toRemove); mListAdapter.notifyDataSetChanged(); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { mCountIncreased = after <= count; } @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} }); } 

Tenga en cuenta que tendrá que cambiar su adaptador para trabajar con la mDisplayedList en lugar de la mFullList .. y eso es todo.

Esto podría dar un poco de sobrecarga cuando su lista contiene un montón de entradas .. pero he trabajado así con una lista de +300 elementos y no noté nada.

Espero que ayude, Vlad

  • Filtrado personalizado en Android con ArrayAdapter
  • ¿Cómo interceptar una intención de Google Maps en Android?
  • Filtro ListView con arrayadapter
  • ¿Cómo puedo usar filtro para emma cuando construyo una prueba de Android con hormigas?
  • Vista de búsqueda de Android en los datos de Firebase
  • IllegalStateException: El contenido del adaptador ha cambiado pero ListView no recibió una notificación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.