2013-05-03 37 views
6

ListView özel bağdaştırıcım (ve yeni uygulanmış olan viewHolder) ile ilgili bazı sorunlar yaşıyorum. Her öğe için bir onay kutusu ile bir ListView var (burada yeni bir şey yok). Sorun şu ki, listemde 9'dan fazla öğe varsa, ilk onay kutusunu işaretlediğimde, her iki öğe için de bir dinleyici varsa, onuncu otomatik olarak (on birinci ile ikinci için aynı) kontrol edilir (ve bir şekilde durum böyle. ListView Görüntüleyici onay kutusu durumu

Burada bunu çözmek için ListView, görünüm geri dönüşümü ve ViewHolder yolu ile pozisyon konuda okuyun: How can I make my ArrayAdapter follow the ViewHolder pattern?

Ama muhtemelen işe yaramıyor çünkü yanlış bir şey yaptı ...

public class PresenceListAdapter extends SimpleAdapter { 
private LayoutInflater inflater; 
private List<Integer> ids; 
private List<String> statuts; 

public PresenceListAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to, List<Integer> ids, List<String> statuts) 
{ 
    super (context, data, resource, from, to); 
    inflater = LayoutInflater.from (context); 
    this.ids = ids; 
    this.statuts= statuts; 

} 

@Override 
public Object getItem (int position) 
{ 
    return super.getItem (position); 
} 

@Override 
public View getView (int position, View convertView, ViewGroup parent) 
{ 

    ViewHolder holder; 

    if (convertView == null) 
    { 
     convertView = inflater.inflate (R.layout.list_text_checkbox, null); 

     holder = new ViewHolder(); 

     holder.btn = (Button) convertView.findViewById(R.id.btnRetard); 
     holder.check = (CheckBox) convertView.findViewById(R.id.checkPresent); 

     if (statuts.get(position).equals("P")) { 
      Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_online); 
      holder.btn.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null); 
      holder.btn.setEnabled(true); 
      holder.check.setChecked(true); 
     } 
     else if(statuts.get(position).equals("R")) 
     { 
      Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_away); 
      holder.btn.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null); 
      holder.btn.setEnabled(true); 
      holder.check.setChecked(true); 
     } 
     else 
     { 
      Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_invisible); 
      holder.btn.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null); 
      holder.check.setChecked(false); 
     } 

     convertView.setTag(holder); 
    } 
    else 
    { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    int id = ids.get(position); 

    if(id != 0) 
    { 
     holder.check.setTag(id); 
     holder.btn.setTag(id); 
    } 

    return super.getView (position, convertView, parent); 
} 

static class ViewHolder { 
    Button btn; 
    CheckBox check; 
} 

Ve benim dinleyici: public void changerPresent (Görünüm v) {

CheckBox checkPresent = (CheckBox) v; 
    int idPersonne = (Integer) checkPresent.getTag(); 
    View parent = (View)v.getParent(); 
    Button btn = (Button) parent.findViewById(R.id.btnRetard); 

    if(checkPresent.isChecked()) { 
     gestion.updatePresence(idPersonne, idSeance, "P"); 

     btn.setEnabled(true); 
     setBtnRetardPresent(btn);   
    } 
    else 
    { 
     gestion.updatePresence(idPersonne, idSeance, "A"); 
     btn.setEnabled(false); 
     setBtnRetardAbsent(btn); 

    } 

} 

ben değilim, bu noktada herhangi bir yardım takdir ediyorum Şu an saatlerce çalışıyorum.

Çok teşekkür ederim.

cevap

13

İşte o iş yapılmış nasıl. Bağdaştırıcınızın getCount() ile aynı boyutta olması gerekir.

Daha sonra getView'inizde, onay kutunuzun setOnCheckedChangedListener onay kutunuzdaki onay kutusunu ZORUNLU OLMALIDIR.

örnek:

holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
    isChecked[position] = isChecked; 
    } 
}); 

holder.checkBox.setChecked(isChecked[position]); 
+0

Mükemmel! Açıklamalarınız için teşekkürler. – jthel

+0

İlginç, lütfen checkchangelistener'ın setChecked'den önce neden çıkması gerektiğini söyler misiniz? Teşekkürler –

+2

onCheckChanged içinde yapmak istediğiniz başka şeyler varsa (liste öğesi rengini, vb. Güncelleyin), dinleyiciyi ayarlamadan önce setChecked'i çağırırsanız bu şeyler olmayacaktır. – josephus

0

sorun listview o) getView( içinde

böylece gördüğünü yöntem geri dönüştürür gerçeğinin olduğunu

 if (convertView == null) 
     { 
    ........ 
     } 
    else 
     { 
      holder = (ViewHolder) convertView.getTag(); 


     } 
    // Uncheck needed boxes here... You need to implement your logic 
     if('position' is checked earlier) 
     holder.check.setChecked(true); 
     else 
     holder.check.setChecked(false); 

dönüştürme boş değilse bakış durumunu yönetmek için kod yazmak gerekir , çünkü kontrol kutularını işaretlenmiş halihazırda kullanılmış bir görünümdür. BTW

if (convertView == null) { 
    viewHolder = new ViewHolder(); 
    convertView.setTag(viewHolder); 
} else { 
    viewHolder = (ViewHolder) convertView.getTag(); 
} 

viewHolder.checkedBox.setChecked(); 

:

0

Aşağıdaki kodu gibi ViewHolder başlatılması dışında CheckedBox devlet belirlesin CheckedBox durumunu saklamak için iki yerine listenin SparseBooleanArray kullanın.

Öncelikle, kontrol devlet için ayrı bir dizi gerekir: