Android: elenco di espansioni personalizzate e problema della casella di controllo. Perché Chechbox State è casuale?

StackOverflow https://stackoverflow.com/questions/9361600

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);
    }
}

}

È stato utile?

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);
                  }
 }
}); 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top