Filtro ListActvity para ArrayAdapter personalizado

He leído varios tutoriales sobre el uso de un filtro simple para una ListActivity, pero simplemente no puedo entender por qué no funciona para mí. El método onTextChanged () de TextWatcher se ejecuta con la cadena correcta a buscar … pero luego no ocurre nada. Creo que el problema podría ser el adaptador personalizado, pero ¿cómo puedo hacer que funcione?

Tal vez podría echarle un vistazo 🙂 Gracias!

package com.RemoteControl; import com.RemoteControl.R; import android.app.ListActivity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; public class RemoteControlPlaylist extends ListActivity { static Handler error_class_Handler; static Handler viewHandler; static EfficientAdapter adapter = null; private static EditText filterText = null; static class EfficientAdapter extends ArrayAdapter<String> { public EfficientAdapter(Context context, int textViewResourceId, int playlistTitle, String[] objects) { super(context, textViewResourceId, playlistTitle, objects); mInflater = LayoutInflater.from(context); } private LayoutInflater mInflater; @Override public int getCount() { return Settings.playlistlength; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.listview, null); holder.text = (TextView) convertView.findViewById(R.string.playlist_title); holder.image = (ImageView) convertView.findViewById(R.string.playlist_play); holder.queue = (TextView) convertView.findViewById(R.string.playlist_queue); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } return convertView; } static class ViewHolder { TextView text, queue; ImageView image; } @Override public String getItem(int position) { return Settings.playlist[position]; } } private static TextWatcher filterTextWatcher = 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) { adapter.getFilter().filter(s); } }; void initialize() { adapter = new EfficientAdapter(this, R.layout.listview, R.string.playlist_title, Settings.playlist); setListAdapter(adapter); filterText = (EditText) findViewById(R.string.search_box); filterText.addTextChangedListener(filterTextWatcher); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.playlist); getListView().setTextFilterEnabled(true); initialize(); error_class_Handler = new Handler(); viewHandler = new Handler(); getListView().setFastScrollEnabled(true); } @Override protected void onDestroy() { super.onDestroy(); filterText.removeTextChangedListener(filterTextWatcher); } } 

Donde el archivo playlist.xml es:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <EditText android:id="@+string/search_box" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="type to filter" android:inputType="text" android:maxLines="1"/> <ListView android:id="@+android:id/list" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1"/> </LinearLayout> 

Y cada fila dentro de ListView es un elemento listview.xml:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+string/playlist_title" android:layout_width="match_parent" android:layout_height="wrap_content" <!-- some layout stuff --> /> <ImageView android:id="@+string/playlist_play" android:src="@drawable/playlist_play" android:layout_width="wrap_content" android:layout_height="wrap_content" <!-- some layout stuff --> /> <TextView android:id="@+string/playlist_queue" android:layout_width="wrap_content" android:layout_height="wrap_content" <!-- some layout stuff --> /> </RelativeLayout> 

Pienso que el filtro estándar del adaptador de la matriz filtra solamente ésa List (arsenal) de objetos, que usted lo pasa en constructor. Pero anula los métodos getCount getItem y etc, por lo que el adaptador no utiliza la lista que pasó en constructor. Pero cuando llama a getFilter().filter(s) filtra esta lista.

Así que tienes clase EfficientAdapter , se extiende ArrayAdapter . Cuando crea la parte de EfficientAdapter – ArrayAdapter creada e inicializada también. En el constructor se pasa una matriz de cadenas y la parte de ArrayAdapter las almacena. El filtro estándar los filtrará en lugar de su lista de lista de configuraciones. Qué puedes hacer: no usar Settings.playlist (y no sobreescribir getItem …), sino usar sólo la lista que getItem en el constructor. Creo que debería funcionar.

Internamente ArrayAdapter tiene los siguientes campos:

 /** * Contains the list of objects that represent the data of this ArrayAdapter. * The content of this list is referred to as "the array" in the documentation. */ private List<T> mObjects; private ArrayList<T> mOriginalValues; 

Filtro de ArrayFilterArrayFilter , filtra mOriginalValues y agrega todos los valores, que coincide con mantiene en mObjects , y luego ArrayAdapter 'muestra' mObjects .

Vea el código fuente de ArrayAdapter (y ArrayFilter ) para ArrayFilter mejor lo que getFilter().filter(s) hace en su caso.

Lea el código fuente de ArrayFilter en la clase ArrayAdapter para aprender de la manera en que los desarrolladores de Android abordan este problema.

La clase ArrayFilter es una clase de Filter personalizada, cuya instancia es utilizada y devuelta por el método getFilter . Estoy seguro de que tendrás todas tus respuestas si lo revisas.

  • Android: Cajón de navegación en múltiples actividades
  • La mejor manera de determinar automáticamente el idioma del usuario
  • ¿Tiene Android SDK intencionalmente utilizar una versión antigua de ProGuard
  • Android Dex: la opción "--core-library" para suprimir este mensaje de error
  • Cómo cambiar el nombre del paquete de una aplicación de Android
  • ¿Por qué el AsyncTask de mi servicio bloquea AsyncTasks de la actividad principal?
  • Android RelativeLayout cambia de color onClick
  • El descubrimiento de servicio falló la excepción utilizando Bluetooth en Android
  • Ahorro de grandes arreglos cortos android
  • Creación de un componente o biblioteca redistribuible para Android
  • ¿Cómo agregar la imagen en un texto de TextView?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.