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.

¿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:

  1. Estoy abriendo una nueva lista
  2. Estoy revisando vamos a decir 2-nd artículo
  3. Empiezo a escribir para filtrar algunos elementos
  4. 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.

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.

  • Deshabilitar el desplazamiento en la vista de lista
  • ¿Cómo configuro una imagen de fondo de ListView vacía?
  • HeaderViewListAdapter se bloquea de forma aleatoria
  • Cómo actualizar la matriz de elementos en una lista AlertDialog construida con AlertDialog.builder después de la creación
  • Cambiar la listaVer el color seleccionado en Android
  • Cómo hacer una cabecera de sección en ListView que siempre se pega en la parte superior?
  • Android: agregar elementos a un ListView con TranscriptMode establecido en Normal
  • ¿Por qué aparece el teclado de Android al agregar un ListView?
  • Desplazamiento con varios ListViews para Android
  • Cómo mantener la posición de desplazamiento de listview cuando se actualiza
  • Xamarin.Forms ListView: establece el color de resaltado de un elemento seleccionado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.