Ho un ListView che visualizza 2 tipi di elementi. Uno di questi tipi contiene CheckedTextView. Come adattatore sto usando un adattatore personalizzato che estende ArrayAdapter con una struttura dati contenente informazioni sugli stati controllati/non selezionati all'interno.Impostazione ListView elemento controllato dall'adattatore
Alcuni degli elementi sono contrassegnati come selezionati (nella mia struttura dati), quindi ovviamente vorrei che le caselle di controllo vengano contrassegnate quando viene creato il ListView. Ho provato a farlo sul metodo getView() nell'adattatore con il metodo setChecked() di CheckedTextView ma non funziona. Ho trovato informazioni che dovrebbero essere fatte a livello di ListView con setItemChecked() e funziona, ma non ha senso per me perché per farlo funzionare dovrei fare un ciclo di tutti gli elementi in attività suCreate() chiamando setItemChecked() per quelli selezionati. L'elenco degli articoli potrebbe essere molto lungo con solo alcuni selezionati, quindi è uno spreco.
Perché chiamare setChecked() in getView() non funziona? C'è un modo migliore per farlo (sono un principiante di Android).
Di seguito è riportato il layout dell'articolo selezionato e l'adattatore.
Disposizione:
<?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"
/>
Adapter:
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];
}
};
}
}
E un pezzo di onCreate di attività()
...
mAdapter = new MultiListAdapter(this, R.id.head, mItems);
setListAdapter(mAdapter);
final ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemsCanFocus(false);
...
Edit:
fino a trovare una soluzione migliore ho implementato il controllo ing in attività:
...
int len = mListView.getCount();
for (int i = 0; i < len; i++) {
if (((MultiChoiceItem) mListView.getItemAtPosition(i)).selected) {
mListView.setItemChecked(i, true);
}
}
...
ho pensato che le prestazioni saranno l'unico problema potenziale, ma ho trovato un altro - molto più grave. L'elenco ha il filtro di testo abilitato (mListView.setTextFilterEnabled (true)). Ecco lo scenario fallimento:
- apro nuova lista
- Im controllo diciamo voce 2-nd
- mi metto a digitare per filtrare alcuni oggetti
- quando il filtraggio viene eseguito, il 2- ND oggetto è ancora verificata, anche se non è quello che ho controllato
Suppongo che setItemChecked() segna una posizione fissa sulla lista controllato mentre ho bisogno di qualcosa che segnerà la voce tenutasi il posizione tHS - mantenere lo stato anche quando la posizione sulla lista cambia.
Mentre il problema delle prestazioni potrebbe essere (fino ad un certo punto) ignorato, questo nuovo problema mi sta davvero bloccando, quindi sarei davvero grato di aiutarlo.
Sto affrontando con lo stesso problema.I miei elementi selezionati scompaiono quando si scorre il listview.Ho provato il codice blok all'interno del mio adattatore, ma ancora i miei elementi selezionati stanno scomparendo quando si scorre la listview – salih
Grazie, ho dovuto cercare un po ' tempo per trovare una soluzione. –