6

Tôi đang có một CheckBox phía trên ListView có các mục Checkbox trong đó. Vì vậy, khi tôi kiểm tra hộp kiểm tôi áp dụng notifyDataSetChanged() để kiểm tra tất cả các kiểm tra tất cả các mục của danh sách. Vì vậy, tại thời điểm đó tôi nhận được các bản ghi cho phương thức getView hai lần, nó có nghĩa là getView được gọi hai lần khi tôi gọi notifyDataSetChanged() chỉ một lần. Vì vậy, bất cứ ai có thể cho tôi biết lý do tại sao tôi nhận được các bản ghi hai lần? Ngoài ra tại sao getView() được gọi hai lần?Hành vi lạ của ListView với CheckBox

Main Class -

checkAll = (CheckBox) findViewById(R.id.my_check_box); 
     checkAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton checkbox, boolean arg1) { 
       adapter.notifyDataSetChanged(); 
      } 
     }); 

Mã cho Adaptor Class -

public class myAdapter extends ArrayAdapter<Model> { 

    private final List<Model> list; 
    private final Activity context; 
    private CheckBox checkAll; 

    public myAdapter(Activity context, List<Model> list, CheckBox checkAll) { 
     super(context, R.layout.row, list); 
     this.context = context; 
     this.list = list; 
     this.checkAll = checkAll; 

    } 

    static class ViewHolder { 
     protected TextView text; 
     protected CheckBox checkbox; 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = null; 
     if (convertView == null) { 
      LayoutInflater inflator = context.getLayoutInflater(); 
      view = inflator.inflate(R.layout.row, null); 
      final ViewHolder viewHolder = new ViewHolder(); 
      viewHolder.text = (TextView) view.findViewById(R.id.label); 
      viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check); 
      viewHolder.checkbox 
        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

         @Override 
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
          Model element = (Model) viewHolder.checkbox.getTag(); 
          element.setSelected(buttonView.isChecked()); 
         } 
        }); 
      view.setTag(viewHolder); 
      viewHolder.checkbox.setTag(list.get(position)); 
     } else { 
      view = convertView; 
      ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position)); 
     } 
     ViewHolder holder = (ViewHolder) view.getTag(); 
     holder.text.setText(list.get(position).getName()); 


     if(checkAll.isChecked() == true){ 
      System.out.println(position+" checked th position"); 
     } 
     else if(checkAll.isChecked() == false){ 
      System.out.println(position+" not checked th position"); 
     } 

     holder.checkbox.setChecked(list.get(position).isSelected());  
     return view; 
    } 
} 

LogCat Output Khi tôi adapter.notifyDataSetChanged(); trên checkboxs CheckAll có thể Kiểm tra Thay đổi Listener.

11-30 20:31:33.751: INFO/System.out(1300): 0 checked th position 
11-30 20:31:33.761: INFO/System.out(1300): 1 checked th position 
11-30 20:31:33.770: INFO/System.out(1300): 2 checked th position 
11-30 20:31:33.780: INFO/System.out(1300): 3 checked th position 
11-30 20:31:33.810: INFO/System.out(1300): 4 checked th position 
11-30 20:31:33.810: INFO/System.out(1300): 0 checked th position 
11-30 20:31:33.831: INFO/System.out(1300): 1 checked th position 
11-30 20:31:33.831: INFO/System.out(1300): 2 checked th position 
11-30 20:31:33.851: INFO/System.out(1300): 3 checked th position 
11-30 20:31:33.860: INFO/System.out(1300): 4 checked th position 

Bạn có thể thấy rằng tôi đầu ra Logcat Tôi nhận được cùng một đầu ra hai lần. Vì vậy, bất cứ ai có thể cho biết lý do tại sao điều này đang xảy ra?

+1

vấn đề này cũng tăng lên với tôi ... +1 –

+2

http: // stackoverflow.com/questions/2618272/custom-listview-adapter-getview-phương pháp-được gọi là-nhiều lần-và-in-no-co kiểm tra này – MKJParekh

+0

@Lalit Poptani Bạn có cuộn không? – Venky

Trả lời

5

Hãy thử làm ListView bạn chiều cao fill_parent.

Lisiview tự thử điều chỉnh một chút theo không gian được cung cấp, đây là những gì tôi đã học được, và có vẻ như đây là lý do đằng sau.

Xem có giúp ích không.

+2

có nghĩa là khi bạn muốn đặt chế độ xem danh sách ở một nửa màn hình..bạn không thể giải quyết vấn đề trên? – MKJParekh

+0

có thể ở một nửa màn hình ở dưới cùng với fill_parent .............. – viv

+0

nếu bạn muốn đặt chế độ xem danh sách ở một nửa màn hình, bạn có thể sử dụng android: layout_weight cho số –

0

đây là chế độ xem bacauseHơn bên trong checkchangelistener sẽ thay đổi cùng với danh sách cuộn. do đó, không có hộp kiểm betwen i'th ánh xạ và viewHolder có thể acheve bằng cách này.

tạo công cụ kiểm tra lớp sepatera thực hiện checnChecnglistener. vượt qua checkchangelistener thông qua constructor.

EG. ngoài getView

class MyCheckChangeLsitenet implements CompoundButton.OnCheckedChangeListener 

ViewHolder viewHolder 
MyCheckChangeLsitenet(ViewHolder viewHolder) 
{ 
this.viewHolder = viewHolder ; 
} 
         @Override 
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
          Model element = (Model) viewHolder.checkbox.getTag(); 
          element.setSelected(buttonView.isChecked()); 
         } 
        }); 

trong GetView

viewHolder.checkbox .setOnCheckedChangeListener (MycheckChangeListenet mới (viewHolder))

+1

Tôi hiện không phải là danh sách cuộn mặc dù nó đưa ra cùng một vấn đề. –

+0

quên cuộn cụm từ. cố gắng làm cho bạn quen thuộc với việc xử lý listView nội bộ. đi qua cách được mô tả. nó sẽ giải quyết vấn đề của bạn –

3

Đây không phải là thực sự là một câu trả lời cho câu hỏi của bạn - nó chỉ là một điều đau khổ đôi mắt của tôi một chút khi tôi thấy điều này:

if(checkAll.isChecked() == true){ 
    System.out.println(position+" checked th position"); 
} 
else if(checkAll.isChecked() == false){ 
    System.out.println(position+" not checked th position"); 
} 

Các if-statement đòi hỏi một biểu boolean và kể từ khi phương pháp isChecked() lợi nhuận một boolean theres không cần phải đối chiếu nó với true/false. Cũng vì boolean chỉ có thể là true hoặc false không cần kiểm tra cả hai. Nói tóm lại, bạn có thể đun sôi trên xuống:

if(checkAll.isChecked()) 
    System.out.println(position+" checked th position"); 
else 
    System.out.println(position+" not checked th position"); 

Đó là nhiều khá nhiều :-)

Đừng coi đây là phê bình các kỹ năng lập trình của bạn - chỉ cần xem nó như là một oppertunity học tập.

+0

Vâng đó nó chỉ là một ứng dụng demo để có được ý tưởng chính xác về vấn đề của tôi. Cảm ơn hơn quá. –

+0

Thật vui nhộn, kaspermoerch! Hãy thử điều này: 'System.out.println (vị trí + (checkAll.isChecked()?" Kiểm tra vị trí thứ ":" không được kiểm tra vị trí thứ "));' –

+0

Điều đó cũng hoạt động, Jeff. Tôi tìm thấy mặc dù, rằng các nhà điều hành ternary nên được sử dụng thận trọng. Nó không phải luôn luôn cải thiện khả năng đọc. – kaspermoerch