Android: elenco di espansioni personalizzate e problema della casella di controllo. Perché Chechbox State è casuale?
-
28-10-2019 - |
Domanda
Il problema è questo:
http://img204.imageshack.us/img204/6071/imginety.png
Perché succede quello ?? Se controllo vicino a "media" ed espando il nodo, Checkmark va al secondo figlio. Non capisco perché
EDIT1: stato di controllo risolto. Si verifica un altro problema !!
Ma forse ho appena capito che il problema non è uno stato della casella di controllo !!! Il problema è la posizione delle righe che cambiano! Se inserisco un array per il controllo quando una vista viene appena caricata, lo stato della casella di controllo funziona bene! Il problema è la posizione di visualizzazione! È questo che succede:
row0: parentA + checkBoxMARKED
row1: parentB + checkBoxNOTmarked
Fai clic su A, e questo dovrebbe accadere:
row0: parentA + checkBoxMARKED
subRow0: --childA
row1: parentB + checkBoxNOTmarked
Ma, al contrario, ciò si verifica (un switch genitore)
row1: parentB + checkBoxNOTmarked
subRow0: --childA
row0: parentA + checkBoxMarked
Ora, se commento questa riga
if(usedPositionParent.contains(convertView.getId())){
return convertView;
}
else{
usedPositionParent.add(convertView.getId());
}
La situazione diventa:
row0: parentA + checkBoxMARKED
row1: parentB + checkBoxNOTmarked
Fai clic su a e si verifica:
row1: parentA + checkBoxNOTmarked
subRow1: --childA
row0: parentB + checkBoxMARKED
Ma in realtà, Pareta è riga 0 !!! Quindi non appare un problema di controllo. È un problema di posizione del genitore !! Cosa ne pensi?
Questo è nuovo codice:
public class ListaEspandibileAdapter extends BaseExpandableListAdapter {
private ArrayList<Object> _objInt;
Context mContext;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//HashMap<Integer,Boolean> checkboxMap = new HashMap<Integer,Boolean>();
CheckListener checkListner;
ArrayList<Integer> usedPositionParent = new ArrayList<Integer>();
CheckBox checkBox;
public ListaEspandibileAdapter(Context context, ArrayList<Object> objList){
mContext = context;
_objInt = objList;
popolaCheckMap();
}
public void popolaCheckMap(){
for(int i=0; i< _objInt.size(); i++)
checkboxMap.put(i, false);
}
@Override
public Object getChild(int arg0, int arg1) {
return null;
}
@Override
public long getChildId(int groupPos, int childPos) {
return childPos;
}
@Override
public View getChildView(int groupPos, int childPos, boolean arg2, View convertView,
ViewGroup parent) {
if (convertView == null) {
Log.i("childView", "my parent is "+ groupPos);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.opportunita_cella_child, null);
EditText descrizioneEditText = (EditText) convertView.findViewById(R.id.opportunita_child_descrizione);
Intervento i = (Intervento) _objInt.get(groupPos);
descrizioneEditText.setText(i.descrizione);
}
return convertView;
}
@Override
public int getChildrenCount(int arg0) {
// i have always one child!
return 1;
}
@Override
public Object getGroup(int arg0) {
return null;
}
@Override
public int getGroupCount() {
return _objInt.size();
}
@Override
public long getGroupId(int groupPos) {
return groupPos;
}
@Override
public View getGroupView(int groupPos, boolean isExpanded, View convertView, ViewGroup parent) {
if(convertView == null) {
Log.i("parentView", "I'am "+ groupPos);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.opportunita_cella, null);
convertView.setId(groupPos);
checkBox = (CheckBox) convertView.findViewById(R.id.opportunita_checkbox);
checkBox.setFocusable(false);
CheckListener checkL = new CheckListener();
checkL.setPosition(groupPos);
checkBox.setOnCheckedChangeListener(checkL);
Intervento intervento = (Intervento) _objInt.get(groupPos);
ImageView imageView = (ImageView) convertView.findViewById(R.id.opportunita_image);
TextView tipoText = (TextView) convertView.findViewById(R.id.opportunita_tipo);
TextView oggettoText = (TextView) convertView.findViewById(R.id.opportunita_oggetto);
TextView urgenzaText = (TextView) convertView.findViewById(R.id.opportunita_urgenza);
TextView dataText = (TextView) convertView.findViewById(R.id.opportunita_data);
TextView oraText = (TextView) convertView.findViewById(R.id.opportunita_ora);
if(intervento.getTipo().equals("Guasto"))
imageView.setImageResource(R.drawable.ic_intervento);
else if(intervento.getTipo().equals("Programmato"))
imageView.setImageResource(R.drawable.image_programmato);
tipoText.setText(intervento.tipo);
oggettoText.setText(intervento.oggetto);
urgenzaText.setText(intervento.urgenza);
if(intervento.urgenza.equals("Immediata"))
urgenzaText.setTextColor(Color.RED);
else if(intervento.urgenza.equals("Alta"))
urgenzaText.setTextColor(Color.YELLOW);
else if(intervento.urgenza.equals("Media"))
urgenzaText.setTextColor(Color.GREEN);
else if(intervento.urgenza.equals("Bassa"))
urgenzaText.setTextColor(Color.WHITE);
Date d = null;
try {
d = sdf.parse(intervento.data);
} catch (ParseException e) {
e.printStackTrace();
}
String yyyy = String.valueOf(d.getYear()+1900);
String MM = String.valueOf(d.getMonth()+1);
String gg = String.valueOf(d.getDate());
String hh = String.valueOf(d.getHours());
String mm = String.valueOf(d.getMinutes());
if(Integer.parseInt(MM) <= 9)
MM = "0"+MM;
if(Integer.parseInt(gg) <= 9)
gg = "0"+gg;
if(Integer.parseInt(hh) <= 9)
hh = "0"+hh;
if(Integer.parseInt(mm) <= 9)
mm = "0"+mm;
dataText.setText(gg+"-"+MM+"-"+yyyy);
oraText.setText(hh+":"+mm);
}
if(usedPositionParent.contains(convertView.getId())){
//checkBox.setChecked(checkboxMap.get(groupPos));
return convertView;
}
else{
usedPositionParent.add(convertView.getId());
}
//if(isExpanded)
// checkBox.setChecked(checkboxMap.get(groupPos));
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int arg0, int arg1) {
return false;
}
public class CheckListener implements OnCheckedChangeListener{
int pos;
public void setPosition(int p){
pos = p;
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Log.i("checkListenerChanged", String.valueOf(pos)+":"+String.valueOf(isChecked));
//checkboxMap.put(pos, isChecked);
}
}
}
Soluzione
Probabilmente a causa del riciclaggio della vista. Stai usando la vista convert in getGroupView?
Assicurati alcune cose
- Che si salva lo stato delle caselle di controllo quando è stato selezionato e impostare il valore in getGroupView.
- Che implementano getGroupid () e getChildid () per avere ID univoci e stabili per gruppo (ID figlio è univoco all'interno del gruppo).
- Preferibilmente sovraccaricare HasstableIds () e impostare su True se puoi promettere ID stabili.
Si noti che il riciclaggio in ExpantableListView è un po 'strano e potrebbe aver bisogno di un lavoro extra da parte tua. Dalla documentazione:
ConvertView La vecchia vista da riutilizzare, se possibile. Dovresti verificare che questa vista non sia nullo e di un tipo appropriato prima di utilizzare. Se non è possibile convertire questa vista per visualizzare i dati corretti, questo metodo può creare una nuova vista. Non è garantito che la convertView sarà stata precedentemente creata da GetGroupView (INT, Boolean, View, ViewGroup).
Altri suggerimenti
Usa questo :
ArrayList<Boolean> item_checked = new ArrayList<Boolean>();
in starting item_checked.add(false)
holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked)
{
itemChecked.set(position, true);
}
else
{
itemChecked.set(position, false);
}
}
});