android - Configuración del elemento ListView verificado desde el adaptador
checkedtextview android (2)
Tengo un ListView que muestra 2 tipos de artículos. Uno de estos tipos contiene CheckedTextView. Como adaptador, estoy usando un adaptador personalizado que extiende ArrayAdapter con una estructura de datos que contiene información sobre los estados marcados / no marcados en su interior.
Algunos de los elementos están marcados como seleccionados (en mi estructura de datos), por lo que, por supuesto, me gustaría que las casillas de verificación se marquen cuando se crea el ListView. Intenté hacerlo con el método getView () en el adaptador con el método setChecked () de CheckedTextView, pero no funciona. Encontré información de que debería hacerse en un nivel de ListView con setItemChecked () y funciona, pero no tiene sentido para mí porque para hacerla funcionar tendría que hacer un bucle de todos los elementos en la actividad onCreate () llamando a setItemChecked () Para los seleccionados. La lista de elementos puede ser muy larga, con solo unos pocos seleccionados, por lo que es un desperdicio.
¿Por qué llamar a setChecked () en getView () no funciona? ¿Hay una mejor manera de hacerlo (soy un novato de Android).
Debajo tienes mi diseño del artículo 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 una pieza de actividad enCreate ()
...
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 mejor solución 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 rendimiento sería el único problema potencial, pero encontré otro, mucho más serio. La lista tiene habilitado el filtro de texto (mListView.setTextFilterEnabled (true)). Aquí está el escenario de falla:
- Estoy abriendo nueva lista
- Estoy revisando digamos 2do artículo
- Empiezo a escribir para filtrar algunos elementos.
- cuando se realiza el filtrado, el elemento 2-nd todavía se verifica aunque no sea el que yo verifiqué
Supongo que setItemChecked () marca una posición fija en la lista marcada mientras necesito algo que marcará el elemento que se mantiene en esta posición, manteniendo el estado incluso cuando la posición en la lista cambia.
Si bien se puede ignorar (hasta cierto punto) el problema de rendimiento, este nuevo problema realmente me está bloqueando, por lo que agradecería cualquier ayuda con él.
Compruebe los pasos Primero en el elemento xml haga que los cambios agreguen una sola línea en la casilla de verificación
`android:onClick="chatWithFriend"`
de modo que cuando haga clic en cheackbox, cree un método en el nombre de la actividad
public void chatWithFriend(View view){}
here you will get the view of check box,
Ahora agregue la línea en getView antes de volver a convertir la vista
holder.checkbox.setTag (posición);
Ahora obtendrás la posición de la casilla de verificación
Espero que esto ayude.
Si usa ListView.CHOICE_MODE_MULTIPLE
o CHOICE_MODE_SINGLE
ListView.CHOICE_MODE_MULTIPLE
CHOICE_MODE_SINGLE
los estados de verificación de los elementos después de que se getView
. Tienes que usar el siguiente constructo:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
((ListView)parent).setItemChecked(position, true);
}
Otra posibilidad es usar ListView.CHOICE_MODE_NONE
y administrar los estados de verificación por usted mismo.