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!
- Dagger 2 problem @ Injecting FirebaseMessagingService
- Android cómo usar / mostrar MediaController con SurfaceView y MediaPlayer para video?
- Android Retrofit sin respuesta
- Error en Android Studio al ejecutar mi aplicación
- Android: Cómo comprobar si el número SMS entrante existe en el teléfono de contacto en BroadcastReceiver y el bloque es el número no existe
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>
- Android internos y limitaciones de memoria / procesador?
- Envío de un SMS en Android
- EditText - cambia el texto mientras escribe
- Fuga de memoria, Spring para Android
- División de una cadena en Java lanza PatternSyntaxException
- Evento onClick no está desencadenando | Androide
- Almacenamiento en antememoria de la baldosa sin conexión con SDK de Android de MapBox
- Cómo importar módulos de SVN en AndroidStudio
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 ArrayFilter
– ArrayFilter
, 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.
- ¿Cómo encontrar el almacenamiento interno (Almacenamiento predeterminado del teléfono) y el almacenamiento externo (tarjeta SD extraíble) en android?
- Android didUpdateHeading (gerente de locación)?