6

enter image description herejak dodać słuchacza do wyboru w widoku karty, Android, ArrayAdapter, onCheckedChanged, OnCheckedChangeListener

Mam ListView, który w drodze ArrayAdapter jest wypełniana przez małe widoki xml sub. każdy mały widok ma tylko dwie rzeczy w środku, pole wyboru i etykietę ciągu obok niego.

Chcę ustawić detektor onCheckedChanged, aby przechwycić zdarzenie użytkownika sprawdzającego lub odznaczając pola wyboru.

na przykład pokazany tu słuchacz:

listView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

@Override 
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 

Toast.makeText(this, "box has been checked", Toast.LENGTH_SHORT).show(); 

} 

}

gdzie mogę umieścić kod słuchacza? i jak to skonfigurować?

kod

dla ArrayAdapter:

public class MobileArrayAdapter extends ArrayAdapter<CheckBoxInfo>{ 
    CheckBoxInfo[] objects; 
    Context context; 
    int textViewResourceId; 

    public MobileArrayAdapter(Context context, int textViewResourceId, 
     CheckBoxInfo[] objects) { 
     super(context, textViewResourceId, objects); 
     this.context = context; 
     this.textViewResourceId = textViewResourceId; 
     this.objects = objects; 

    } 

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


      if ((row_layout_view == null)){ 


       LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       row_layout_view = inflater.inflate(R.layout.row_layout, null); 
      } 

      //CheckBoxInfo item = objects.get(position); // for arrayList 
      CheckBoxInfo item = objects[position]; 

      if(item != null){ 

      TextView textView = (TextView) row_layout_view.findViewById(R.id.textView1); 
      CheckBox checkBox = (CheckBox) row_layout_view.findViewById(R.id.checkBox1); 

      if(item !=null){ 
      textView.setText(item.checkBoxName); 
      checkBox.setChecked(item.checkBoxState); 
       } 
      } 
      return row_layout_view; 
    } 


} 

Odpowiedz

29

Nie używaj przykład listView.setOnCheckedChangeListener lub onCheckedChanged kodu.

Przede wszystkim dla CheckBox należy użyć setOnClickListener() zamiast setOnCheckedChangeListener(). Możesz sprawdzić stan wewnątrz funkcji onClick().

Po drugie, umieść swój setOnClickListener() wewnątrz funkcji getView() adaptera list.

Przykład:

checkBox.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View arg0) { 
     final boolean isChecked = checkBox.isChecked(); 
     // Do something here. 
    } 
}); 
+3

I nie sądzę, że to działa, ponieważ poglądów recyklingu ListView. Gdy przewiniesz w dół, a wybrany convertView zostanie poddany recyklingowi, zaznaczony wiersz zostanie odznaczony. Jak sobie z tym poradzisz? –

+4

To jest prawidłowe zachowanie. Kiedy widok zostaje ponownie użyty, wszystkie jego podrzędne elementy podrzędne mają cechy widoku bez znaczenia, który został poddany recyklingowi. Dlatego za każdym razem musisz aktualizować wszystkie widoki i ich atrybuty w 'getView()'. Obejmuje to ustawienie wartości CheckBox oraz jej "OnClickListener". Podsumowując, zachowaj słuchacza i dodaj 'checkBox.setChecked()', aby ustawić go na wartość oczekiwaną, w przypadku, gdy widok poddany recyklingowi (lub nowemu) ma inne ustawienie. –

1

Dziękuję David! w odniesieniu do komentarza HukeLau_DABA, rozwiązałem go, aktualizując obiekt widoku listy za pomocą wartości CheckBox wewnątrz OnClickListener(). W moim przypadku mam listę miejsc, jak widać w następnym kodzie:

holder.placeCheckBox.setOnClickListener(new View.OnClickListener() { 

     //please note that objPlace, position and holder must be declared 
     //as final inside the getView() function scope. 
      @Override 
      public void onClick(View arg0) { 
       final boolean isChecked = holder.placeCheckBox.isChecked(); 
       if (isChecked){ 
        objPlace.setItemChecked("yes"); 
       }else{ 
        objPlace.setItemChecked("no"); 
       } 

       placesList.set(position,objPlace); // updating the list with the updated object 

      } 
     }); 
1

nie odnoszą się do „holder.placeCheckBox” w swojej onClickListener, należy odwołać się do wyświetlenia, które są przekazywane przez onClick i oddanych do checkbox więc kod powinien wyglądać tak:

holder.placeCheckBox.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 
      boolean isChecked = ((CheckBox)arg0).isChecked(); 
      if (isChecked){ 
       objPlace.setItemChecked("yes"); 
      }else{ 
       objPlace.setItemChecked("no"); 
      } 

      placesList.set(position,objPlace); // updating the list with the updated object 

     } 
    }); 
0

można spróbować to:

holder.placeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
     Log.d(TAG, "onCheckedChanged: " + holder.placeCheckBox.getText() + " " + (b ? "selected":"deselected")); 
    } 
});