Configuración del elemento ListView marcado desde Adapter
Tengo un ListView que exhibe 2 clases de artículos. Uno de estos tipos contiene CheckedTextView. Como un adaptador que estoy usando el adaptador de encargo que extiende ArrayAdapter con la estructura de datos que contiene la información sobre estado check / unchecked adentro.
Algunos de los elementos están marcados como seleccionados (en mi estructura de datos), por supuesto, me gustaría que las casillas de verificación que se marcará cuando se crea el ListView. Intenté hacerlo en método getView () en el adaptador con el método setChecked () de CheckedTextView, pero no funciona. Encontré información que debería hacerse en un nivel de ListView con setItemChecked () y funciona, pero no tiene sentido para mí, porque para que funcione tendría que hacer un bucle en todos los elementos de la actividad onCreate () llamando a setItemChecked () para los seleccionados. La lista de artículos puede ser muy larga con sólo unos pocos seleccionados por lo que es un desperdicio.
- ClassCastException no puede convertir LinearLayout $ LayoutParams a AbsListView $ LayoutParams al establecer ListView Header
- Cómo mostrar los contactos en un listview en Android para Android api 11+
- ¿Cómo el ajuste baselineAligned a false mejora el rendimiento en LinearLayout?
- Mostrar siempre la barra de desplazamiento para ListView
- Picasso no puede cargar imágenes para alguna URL (sin caracteres especiales)
¿Por qué llamar a setChecked () en getView () no funciona? ¿Hay una mejor manera de hacer esto (soy un novato de Android).
A continuación tiene mi plan de artículos y el adaptador.
Diseño:
<?xml version="1.0" encoding="utf-8"?> <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:gravity="center_vertical" android:textAppearance="@style/listViewItemText" android:checkMark="?android:attr/listChoiceIndicatorMultiple" android:paddingLeft="6dp" android:paddingRight="6dp" />
Adaptador:
package com.melog.re.droid.search; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.TextView; import com.melog.re.droid.core.R; import com.melog.re.droid.search.MultiCriterionValue.MultiCriterionSingleValue; import com.melog.re.droid.search.MultiListAdapter.MultiChoiceItem; public class MultiListAdapter extends ArrayAdapter<MultiChoiceItem> { private static final int VIEW_TYPES_COUNT = 2; public static final int VIEW_TYPE_GROUP = 0; public static final int VIEW_TYPE_ITEM = 1; private LayoutInflater mInflater; public MultiListAdapter(Context context, int textViewResourceId, List<MultiChoiceItem> objects) { super(context, textViewResourceId, objects); mInflater = LayoutInflater.from(context); } @Override public int getItemViewType(int position) { MultiChoiceItem item = getItem(position); return (item.children.size() == 0) ? VIEW_TYPE_ITEM : VIEW_TYPE_GROUP; } @Override public int getViewTypeCount() { return VIEW_TYPES_COUNT; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO: optymalizacja ViewHolder MultiChoiceItem item = getItem(position); int viewType = getItemViewType(position); switch (viewType) { case VIEW_TYPE_GROUP: if (convertView == null) { convertView = mInflater.inflate(R.layout.multi_choice_group_item, parent, false); } TextView groupLabel = (TextView) convertView.findViewById(android.R.id.text1); groupLabel.setText(item.toString()); break; case VIEW_TYPE_ITEM: if (convertView == null) { convertView = mInflater.inflate(R.layout.multi_choice_child_item, parent, false); } CheckedTextView itemLabel = (CheckedTextView) convertView.findViewById(android.R.id.text1); itemLabel.setText(item.toString()); itemLabel.setChecked(item.selected); break; } return convertView; } public static class MultiChoiceItem implements Parcelable { public static final int CONTENTS_DESCR = 1; public String label; public String value; public boolean selected = false; public ArrayList<MultiChoiceItem> children = new ArrayList<MultiChoiceItem>(); public MultiChoiceItem(String l, String v, boolean sel) { label = l; value = v; selected = sel; } public MultiChoiceItem(MultiCriterionSingleValue v) { label = v.toString(); value = v.value; } public MultiChoiceItem(Parcel in) { label = in.readString(); value = in.readString(); selected = (in.readInt() == 1); } @Override public String toString() { return label; } @Override public int describeContents() { return CONTENTS_DESCR; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(label); dest.writeString(value); dest.writeInt(selected ? 1 : 0); } public static final Parcelable.Creator<MultiChoiceItem> CREATOR = new Parcelable.Creator<MultiChoiceItem>() { public MultiChoiceItem createFromParcel(Parcel in) { return new MultiChoiceItem(in); } public MultiChoiceItem[] newArray(int size) { return new MultiChoiceItem[size]; } }; } }
Y un pedazo de la actividad onCreate ()
... mAdapter = new MultiListAdapter(this, R.id.head, mItems); setListAdapter(mAdapter); final ListView listView = getListView(); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setItemsCanFocus(false); ...
Editar:
Hasta encontrar una solución mejor implementé la comprobación en la Actividad:
... int len = mListView.getCount(); for (int i = 0; i < len; i++) { if (((MultiChoiceItem) mListView.getItemAtPosition(i)).selected) { mListView.setItemChecked(i, true); } } ...
Pensé que el funcionamiento sería el único problema potencial pero encontré otro – mucho más serio. La lista tiene filtro de texto habilitado (mListView.setTextFilterEnabled (true)). Aquí está el escenario de error:
- Estoy abriendo una nueva lista
- Estoy revisando vamos a decir 2-nd artículo
- Empiezo a escribir para filtrar algunos elementos
- cuando se hace el filtrado, el 2-nd artículo todavía se comprueba aunque no es el que he comprobado
Supongo que setItemChecked () marca una posición fija en la lista marcada mientras que necesito algo que marque el ítem mantenido en esta posición, manteniendo el estado incluso cuando cambie la posición en la lista.
Mientras que el problema de rendimiento podría ser (hasta cierto punto) ignorado – este nuevo problema es realmente el bloqueo de mí, por lo que realmente agradecería cualquier ayuda con él.
- ArrayAdapter - filtrado con múltiples términos de búsqueda
- Mejores prácticas que combinan vistas de lista y no de lista, como el Mercado
- Tire para actualizar y cargar en listview
- Problema al agregar pie de página a ListView
- Android: Cambia la imagen de un elemento en particular en listview
- ListView en ArrayAdapter orden se mezcla cuando se desplaza
- Seleccione sólo un botón de radio de la vista de lista
- Android - EditTexts dentro de ListView vinculado a Custom ArrayAdapter - manteniendo un registro de los cambios
Si utiliza ListView.CHOICE_MODE_MULTIPLE
o CHOICE_MODE_SINGLE
los estados de comprobación de los elementos serán reemplazados por ListView después de que se esté llamando a getView
. Tienes que usar la siguiente construcción:
@Override public View getView(int position, View convertView, ViewGroup parent) { ((ListView)parent).setItemChecked(position, true); }
Otra posibilidad es utilizar ListView.CHOICE_MODE_NONE
y administrar los estados de comprobación por usted mismo.
Compruebe los pasos Primero en xml del artículo haga los cambios agregue la sola línea en casilla de verificación
`android:onClick="chatWithFriend"`
por lo que cuando haga clic en cheackbox, a continuación, crear el método en un nombre de actividad
public void chatWithFriend(View view){} here you will get the view of check box,
Ahora agregue la línea en getView antes de devolver convertir vista
holder.checkbox.setTag (posición);
Ahora u obtendrá la posición de la casilla de verificación
Espero que esto ayude.