2010-10-12 12 views
5

Tôi có một Android ListView có các mục có hộp kiểm.Thay đổi hộp kiểm có giá trị hai lần

Hộp kiểm được chọn theo mặc định. Khi bỏ chọn, nó sẽ bị xóa khỏi danh sách.

Vấn đề là onCheckedChanged đang được bắn hai lần: khi tôi chạm vào hộp kiểm để bỏ chọn nó (với isCheckedfalse) và sau khi tôi loại bỏ các mục (với isCheckedtrue).

Đây là mã có liên quan của ArrayAdapter tôi:

public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.item, parent, false); 
     holder = new ViewHolder(); 
     holder.check = (CheckBox) convertView.findViewById(R.id.check); 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    final Object item = this.getItem(position); 
    holder.check.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if (!isChecked) { 
       remove(item); // This somehow calls onCheckedChanged again 
      } 
     } 
    }); 
    return convertView; 
} 

Tôi đang làm gì sai?

+0

Phương thức 'remove()' làm gì, vì đó không phải là phương thức trên 'ListAdapter'? – CommonsWare

+0

Tôi đang sử dụng ArrayAdapter. Theo mã nguồn Android, phương thức remove loại bỏ mục khỏi mảng và thông báo rằng dữ liệu đã bị thay đổi. – hpique

Trả lời

0

Tôi gặp phải sự cố tương tự.

Sau khi một số nghiên cứu tôi phát hiện ra rằng có một hành vi tương tự trong RadioGroup cho setCheckChangeListener.

Gắn thẻ làm mọi thứ lộn xộn, có vẻ như một lỗi.

Giải pháp thay thế của tôi đã đặt thẻ thành vô giá ở cuối trình nghe Nó làm việc cho tôi.

private OnCheckedChangeListener checkBoxitemClickListener = new OnCheckedChangeListener() { 

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 


     if(isChecked) 
     {    
      //do smth 
     }else 
     { 
      //do smth 
     } 

     buttonView.setTag(null);       
    } 
}; 

Nếu bạn cần cập nhật ListView của mình sau, đừng quên gọi "notifyDataSetChanged" trên bộ điều hợp của bạn.

Chúc mừng

5

Tôi gặp phải vấn đề tương tự, có vẻ như đó là lỗi Android này hai lần thực hiện phương thức onCheckChanged.

Giải pháp của tôi: triển khai onClickListener, thay vì onCheckedChangedListener.

Something như thế này:

private final class CheckUpdateListener implements OnClickListener { 

    private Group parent; 
    private boolean isChecked; 

    private CheckUpdateListener(Group parent) { 

     this.parent = parent; 

    } 

    @Override 
    public void onClick(View box) { 
     this.isChecked = !parent.isChecked(); 

     parent.setChecked(isChecked); 

     notifyDataSetChanged(); 

    } 

} 
+0

Vâng, tôi nghĩ rằng việc nghe onCheckedChange là quá mức cần thiết và không phải là điều đúng đắn để làm trong hầu hết các trường hợp. Tuy nhiên, vấn đề cơ bản đối với tôi là có được góc nhìn phù hợp, tức là View không giống với đối tượng dữ liệu được xem. – rwst

2

Tôi đã có một vấn đề tương tự và chỉ cần giải quyết nó đúng mà không cần phải tránh sử dụng các mục đích OnCheckedChangeListener.

Vấn đề Mã

holder.someCheckBox.setChecked(false); 
holder.someCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { 
     ... 
    } 
}); 

Lưu ý tôi đặt tình trạng kiểm tra trước tôi đặt người nghe, điều này là để ngăn chặn người nghe từ bắn vào sáng tạo.

Tuy nhiên, người nghe bắt đầu kích hoạt sự kiện kiểm tra chính xác hai lần chỉ sau khi bộ điều hợp buộc phải được tạo lại hoặc thông qua việc sử dụng notifyDataSetChanged.

Giải pháp

Rõ ràng người nghe trước thiết lập trạng thái kiểm tra, thậm chí trong quá trình tạo ở đây.

holder.someCheckBox.setOnCheckedChangeListener(null); 
holder.someCheckBox.setChecked(false); 
holder.someCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { 
     ... 
    } 
}); 

Bây giờ, mọi trình lắng nghe dư sẽ không được kích hoạt khi đặt giá trị ban đầu của hộp kiểm.