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


Ampliación de ArrayAdapter en android

Necesito anular un método de getFilter() de la clase ArrayAdapter y encontré el código fuente de aquí en el github

 //package name import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.content.Context; import android.util.Log; import android.widget.ArrayAdapter; import android.widget.Filter; import android.widget.Filterable; public class CustomAdapter<T> extends ArrayAdapter<T> implements Filterable{ private ArrayList<T> mOriginalValues; private List<T> mObjects; private CustomFilter mFilter; private final Object mLock = new Object(); public CustomAdapter(Context context, int textViewResourceId, T[] objects) { super(context, textViewResourceId, objects); mObjects = Arrays.asList(objects); // TODO Auto-generated constructor stub } @Override public Filter getFilter() { // TODO Auto-generated method stub if (mFilter == null) { mFilter = new CustomFilter(); } return mFilter; } private class CustomFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); Log.d("bajji", "its ---> " + prefix); if (mOriginalValues == null) { synchronized (mLock) { mOriginalValues = new ArrayList<T>(mObjects); } } if (prefix == null || prefix.length() == 0) { ArrayList<T> list; synchronized (mLock) { list = new ArrayList<T>(mOriginalValues); } results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList<T> values; synchronized (mLock) { values = new ArrayList<T>(mOriginalValues); } final int count = values.size(); final ArrayList<T> newValues = new ArrayList<T>(); final ArrayList<T> approxValues = new ArrayList<T>(); final ArrayList<T> secondApproxValues = new ArrayList<T>(); for (int i = 0; i < count; i++) { final T value = values.get(i); final String valueText = value.toString().toLowerCase(); boolean flag = true; // First match against the whole, non-splitted value if (valueText.startsWith(prefixString)) { newValues.add(value); flag = false; } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0, in case valueText starts with space(s) for (int k = 0; k < wordCount; k++) { if (words[k].startsWith(prefixString)) { newValues.add(value); flag = false; break; } } } if(flag) { if(approxMatch(valueText, prefixString) <= 3) { //change the stuff and do a levi work approxValues.add(value); } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0, in case valueText starts with space(s) for (int k = 0; k < wordCount; k++) { if(approxMatch(words[k], prefixString) <= 3) { //leve work secondApproxValues.add(value); break; } } } } } newValues.addAll(approxValues); newValues.addAll(secondApproxValues); results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked mObjects = (List<T>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } } private int approxMatch (String s, String t) { // an approxmimate string matching algo return p; } } 

El problema es que el método getFilter tiene un objeto de una clase interna privada ArrayFilter que tiene un método peformFiltering y necesito poner un código diferente allí así que tengo que overide la clase. Y recibo una excepción en el método.

En la clase derivada que extiende ArrayAdapter i creó una clase privada interna que es similar a ArrayFilter y lo llamó MyFilter y recibo la misma excepción de nuevo en el método performFiltering .

He encontrado una solución para resolver mi problema. Copié todo el código en la clase ArrayAdapter y creé una nueva clase llamada MyAdapter y MyAdapter algún código dentro de la clase interna ArrayFilter y la aplicación funciona de la manera que yo quería. Pero siento que no es la mejor solución.

Android tiene varios niveles de api por lo que si el adaptador de matriz se cambia en diferentes niveles de api, entonces tengo que añadir los cambios en mis códigos a. Así que me siento la mejor manera es extender la clase ArrayAdapter para crear MyAdapter lugar de simplemente copiar y pegar el código de la ArrayAdapter

¿Cómo puedo anular la clase privada interna de una clase padre ..?

Edit: La excepción que recibo .. Excepción

Edit2: Ahora he añadido el código completo en la pregunta. Y funciona perfectamente si copiar y editar el adaptador de la matriz .. el problema es sólo cuando extiendo .. !! Ahora el código y la búsqueda está funcionando perfectamente. Lo he comprobado con Log.i .. pero la lista desplegable para la sugerencia de auto completo en la interfaz de usuario no está funcionando .. sólo obtener para el primer carácter i tipo el siguiente carácter de filtrado se lleva a cabo, pero UI actualización no se lleva a cabo.

  • Convertir objeto complejo de Java en Json
  • ¿Es posible usar la API de Java 8 Stream en la API de Android <24?
  • Cobertura del código de prueba de Android, Eclipse
  • No se puede resolver el símbolo @ integer / google_play_services_version para intellij
  • Android: Fragmentos, SQLite y cargadores
  • Cómo el código fuente de Android minify y ofuscar?
  • Uso de Picasso para cargar una imagen en un mapa de bits
  • Cómo obtener un servicio "enlazado" de Android para sobrevivir a un reinicio de la configuración
  • 4 Solutions collect form web for “Ampliación de ArrayAdapter en android”

    Después de una cierta ayuda de la comunidad del stackoverflow quité la excepción y más adelante descubrí que las sugerencias que se vuelven no cambian realmente porque los mObjects fueron vueltos de la clase estupenda o de la clase baja. El problema era que había dos métodos públicos getCount() y getItem(int position) que obtiene la cuenta y extrae la lista de mObjects de la clase base. Así que solo tengo que añadir esos dos métodos en mi clase.

     public int getCount() { return mObjects.size(); } public T getItem(int position) { return mObjects.get(position); } 

    Ahora se mObjects de la clase derivada. Cuáles son los actualizados en la lista desplegable de la interfaz de usuario.

    No soy un experto en java, pero esto soluciona mi problema. Si tiene alguna sugerencia para mejorar el código, agréguelo en comentarios o siéntase libre de editar la respuesta.

    Actualizar:

    Debe reemplazar el método toString() en su clase T y devolver la cadena de criterio de filtro.

    Por ejemplo,

     class T { String firstName; String lastName; ... ... @override String toString() { return firstName + lastName; } } 

    Por defecto, la implementación toString() de la clase Object devuelve getClass().getName() + '@' + Integer.toHexString(hashCode())

    Original:

    La referencia de la lista de arreglos se debe pasar al constructor ArrayAdapter . Creo que no estás haciendo esto y por lo tanto no es capaz de obtener una lista de filtrado.

    En este código de ejemplo objects referencia de matriz de objects se pasa al super constructor.

     public CustomAdapter(Context context, int tvResId, ArrayList<String> objects) { super(context, textViewResourceId, objects); this.objects = objects; } 

    Si su filtrado se basa en las cadenas simples en los elementos de la lista, entonces puede implementar TextWatcher como lo sugiere @Iiorry. Pero si el filtrado es poco complejo que eso, entonces usted necesita para implementar también Filterable .

    No necesitas implementar tu propio filtro … solo sobreescribe getFilter como @Waqas sugirió.

    Esto es lo que hice y funciona. Siéntase libre de ajustarlo a sus necesidades …

    Espero que ayude.

    El EditText (searchFilder):

     searchFilter.addTextChangedListener(mOnSearchBoxTextChanged); private TextWatcher mOnSearchBoxTextChanged = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { mAdapter.getFilter().filter(s.toString()); } }; 

    El adaptador getFilter ():

      class MyAdapter extends BaseAdapter implements Filterable { //the rest of the adapter.... @Override public Filter getFilter() { if (newFilter == null) { newFilter = new Filter() { @Override protected void publishResults(CharSequence prefix, FilterResults results) { CLog.logD( "Friends list filtered"); mAdapter.notifyDataSetChanged(); } @Override protected FilterResults performFiltering(CharSequence constraint) { constraint = constraint.toString().toLowerCase(); filteredFriendList = new ArrayList<FriendsListItemView>(); if (constraint!= null && constraint.toString().length() > 0) { for (int i = 0; i < friendsList.size(); i++) { FriendsListItemView newFriend = friendsList.get(i); String name = newFriend.userName.getText().toString(); if (name.toLowerCase().contains(constraint)) { filteredFriendList.add(newFriend); } } } else { if (filteredFriendList.size() == 0) { filteredFriendList = friendsList; } } FilterResults newFilterResults = new FilterResults(); newFilterResults.count = filteredFriendList.size(); newFilterResults.values = filteredFriendList; return newFilterResults; } }; } return newFilter; } } 

    Tal vez esto puede ayudarle:

     import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.content.Context; import android.util.Log; import android.widget.ArrayAdapter; import android.widget.Filter; public class CustomAdapter<T> extends ArrayAdapter<T> { private final ArrayList<T> mOriginalValues; private List<T> mObjects; private CustomFilter mFilter; private final Object mLock = new Object(); public CustomAdapter(Context context, int textViewResourceId, T[] objects) { super(context, textViewResourceId, objects); mObjects = Arrays.asList(objects); mOriginalValues = (ArrayList<T>) Arrays.asList(objects); // TODO Auto-generated constructor stub } @Override public Filter getFilter() { // TODO Auto-generated method stub if (mFilter == null) { mFilter = new CustomFilter(); } return mFilter; } private class CustomFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); Log.d("bajji", "its ---> " + prefix); if (prefix == null || prefix.toString().trim().length() == 0) { ArrayList<T> list; synchronized (mLock) { list = new ArrayList<T>(mOriginalValues); } results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList<T> values; synchronized (mLock) { values = new ArrayList<T>(mOriginalValues); } final int count = values.size(); final ArrayList<T> newValues = new ArrayList<T>(); final ArrayList<T> approxValues = new ArrayList<T>(); final ArrayList<T> secondApproxValues = new ArrayList<T>(); for (int i = 0; i < count; i++) { final T value = values.get(i); final String valueText = value.toString().toLowerCase(); boolean flag = true; // First match against the whole, non-splitted value if (valueText.startsWith(prefixString)) { newValues.add(value); flag = false; } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0, in case valueText starts with space(s) for (int k = 0; k < wordCount; k++) { if (words[k].startsWith(prefixString)) { newValues.add(value); flag = false; break; } } } if(flag) { if(approxMatch(valueText, prefixString) <= 3) { //change the stuff and do a levi work approxValues.add(value); } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0, in case valueText starts with space(s) for (int k = 0; k < wordCount; k++) { if(approxMatch(words[k], prefixString) <= 3) { //leve work secondApproxValues.add(value); break; } } } } } newValues.addAll(approxValues); newValues.addAll(secondApproxValues); results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked mObjects = (List<T>) results.values; notifyDataSetChanged(); clear(); for(T tmp : mObjects){ add(tmp); } notifyDataSetChanged(); } } private int approxMatch (String s, String t) { // an approxmimate string matching algo return p; } } 

    Ahora en el método getView del adaptador, necesita referirse al objeto mObjects para obtener los valores disponibles recientes para ListView

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.