Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Filtrado personalizado ArrayAdapter en ListView

Soy un begginer en Android, pero he intentado hacer un filtro de listview personalizado y yo funcionó de alguna manera. El único problema que tengo es que el ArrayList que guardé todos los valores ("original" ArrayList), está consiguiendo más bajo y más bajo en artículos en cada filtrado. No puedo explicar esto pero pensé que puedes ayudarme de alguna manera.

De todos modos aquí es el Custom ArrayAdaptor:

  • ¿Cómo obtener tareas recientes en Android "L"?
  • Renderizar archivos epub en android
  • Android Days entre dos fechas
  • Adaptador de cursor personalizado que llama a bindView varias veces
  • Leer / escribir en un archivo XML externo en Android
  • Cómo implementar SQLCipher cuando se utiliza SQLiteOpenHelper
  • public class PkmnAdapter extends ArrayAdapter<Pkmn> { private ArrayList<Pkmn> original; private ArrayList<Pkmn> fitems; private Filter filter; public PkmnAdapter(Context context, int textViewResourceId, ArrayList<Pkmn> items) { super(context, textViewResourceId, items); this.original = items;//new ArrayList<Pkmn>(); this.fitems = items;//new ArrayList<Pkmn>(); } @Override public void add(Pkmn item){ original.add(item); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.row, null); } Pkmn pkmn = original.get(position); if (pkmn != null) { TextView tt = (TextView) v.findViewById(R.id.RlabPName); TextView dex = (TextView)v.findViewById(R.id.RlabDex); ImageView img = (ImageView)v.findViewById(R.id.RimgPkmn); if (tt != null) { tt.setText(pkmn.getName()); } if (dex != null){ dex.setText(CalcDex(pkmn.getId())); } if (img != null){ int resId = getContext().getResources().getIdentifier("dex" + pkmn.getId(), "drawable", "com.compileguy.pokebwteam"); img.setImageResource(resId); } } return v; } @Override public Filter getFilter() { if (filter == null) filter = new PkmnNameFilter(); return filter; } private class PkmnNameFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); String prefix = constraint.toString().toLowerCase(); if (prefix == null || prefix.length() == 0) { ArrayList<Pkmn> list = new ArrayList<Pkmn>(original); results.values = list; results.count = list.size(); } else { final ArrayList<Pkmn> list = original; int count = list.size(); final ArrayList<Pkmn> nlist = new ArrayList<Pkmn>(count); for (int i=0; i<count; i++) { final Pkmn pkmn = list.get(i); final String value = pkmn.getName().toLowerCase(); if (value.startsWith(prefix)) { nlist.add(pkmn); } } results.values = nlist; results.count = nlist.size(); } return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { fitems = (ArrayList<Pkmn>)results.values; clear(); int count = fitems.size(); for (int i=0; i<count; i++) { Pkmn pkmn = (Pkmn)fitems.get(i); add(pkmn); } if (fitems.size() > 0) notifyDataSetChanged(); else notifyDataSetInvalidated(); } } private String CalcDex(int id){ String s = String.valueOf(id); if (s.length() == 1) s = "00"+s; else if (s.length() == 2) s = "0"+s; return '#'+s; } 

    }

    NOTA: El listview muestra correctamente los elementos pero cuando para exaple elimino una letra en el editbox (que desencadena el filtrado) aquí es donde empiezan los problemas.

    — EDITAR —

    @ Janusz: Muchas gracias por su respuesta. Eso resolvió mi problema.

    Aquí está el código fuente que funciona para mí, así que si alguien tiene el mismo problema que podría intentar este:

     private ArrayList<Pkmn> original; private ArrayList<Pkmn> fitems; private Filter filter; public PkmnAdapter(Context context, int textViewResourceId, ArrayList<Pkmn> items) { super(context, textViewResourceId, items); this.original = new ArrayList<Pkmn>(items); this.fitems = new ArrayList<Pkmn>(items); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.row, null); } Pkmn pkmn = fitems.get(position); if (pkmn != null) { TextView tt = (TextView) v.findViewById(R.id.RlabPName); TextView dex = (TextView)v.findViewById(R.id.RlabDex); ImageView img = (ImageView)v.findViewById(R.id.RimgPkmn); if (tt != null) { tt.setText(pkmn.getName()); } if (dex != null){ dex.setText(CalcDex(pkmn.getId())); } if (img != null){ int resId = getContext().getResources().getIdentifier("dex" + pkmn.getId(), "drawable", "com.compileguy.pokebwteam"); img.setImageResource(resId); } } return v; } @Override public Filter getFilter() { if (filter == null) filter = new PkmnNameFilter(); return filter; } private class PkmnNameFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); String prefix = constraint.toString().toLowerCase(); if (prefix == null || prefix.length() == 0) { ArrayList<Pkmn> list = new ArrayList<Pkmn>(original); results.values = list; results.count = list.size(); } else { final ArrayList<Pkmn> list = new ArrayList<Pkmn>(original); final ArrayList<Pkmn> nlist = new ArrayList<Pkmn>(); int count = list.size(); for (int i=0; i<count; i++) { final Pkmn pkmn = list.get(i); final String value = pkmn.getName().toLowerCase(); if (value.startsWith(prefix)) { nlist.add(pkmn); } } results.values = nlist; results.count = nlist.size(); } return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { fitems = (ArrayList<Pkmn>)results.values; clear(); int count = fitems.size(); for (int i=0; i<count; i++) { Pkmn pkmn = (Pkmn)fitems.get(i); add(pkmn); } } } } 

  • Cómo evitar que se llamen ambos: onItemClicked y onTextChanged en AutoCompleteTextView
  • Android, agente de usuario de webview vs agente de usuario de navegador
  • ActionBar en PreferenceFragment no volver a calcular la altura y el tamaño de fuente
  • Android Studio: El módulo no aparecerá en "Editar configuración"
  • OnTimeSet también se llama al descartar TimePickerDialog
  • ListAdapter Filtro que no sea el uso de cadenas?
  • 3 Solutions collect form web for “Filtrado personalizado ArrayAdapter en ListView”

    Su problema son estas líneas:

     this.original = items; this.fitems = items; 

    Elementos es la lista que utiliza para su ListView y ponerla en dos variables diferentes no hace dos listas diferentes fuera de ella. Usted está dando solamente a los artículos de la lista dos nombres diferentes.

    Puedes usar:

     this.fitems = new ArrayList(items); 

    Que debe generar una nueva Lista y los cambios en esta lista solo cambiarán la lista de fitems.

    Puede lograr el mismo efecto creando un método toString() en su clase Pkmn que devuelve el valor que desea filtrar.

    La mejor manera que encontré para filtrar ArrayAdapter es crear mi propia clase de filtro:

     private class MyFilter extends Filter 

    Entonces en esa función crear la nueva matriz de objetos para mostrar después del filtro (se puede encontrar una buena aplicación en el código fuente de la class ArrayAdapter )

     @Override protected FilterResults performFiltering(CharSequence prefix) 

    Ahora el truco está en este método

     @Override protected void publishResults(CharSequence constraint, FilterResults results) 

    Cuando utiliza el adaptador de matriz no puede hacer esto:

     myAdapterData = results.values 

    Desde entonces se desconectan los datos de los superdatos, debe hacer esto para mantener su referencia a la matriz de datos super original:

     data.clear(); data.addAll((List<YourType>) results.values); 

    Y luego anular

    GetFilter ()

    En su adaptador, por ejemplo:

     @Override public Filter getFilter() { if (filter == null) { filter = new MyFilter(); } return filter; } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.