2010-10-24 32 views
8

Tôi đã tạo một ListView tùy chỉnh bằng cách mở rộng SimpleCursorAdapter. Kết quả là IMAGE + CheckedTextView (Text + Checkbox).Android Bấm vào danh sáchMục kiểm tra hộp kiểm sai

Khi tôi bấm lâu một mục, mọi thứ hoạt động tốt - tôi nhận được đúng ID và chi tiết của mục được nhấp.

Sự cố xảy ra khi tôi cố đánh dấu một mục là đã chọn nhưng kiểm tra hộp kiểm sai.

Ví dụ: Tôi có 9 mục trong danh sách của tôi, được sắp xếp 1-9. nếu tôi bấm vào listItem 1, hộp kiểm trên dòng 9 đang được kiểm tra. nếu tôi bấm vào mục 4, hộp kiểm trên dòng 6 đang được kiểm tra và nếu tôi bấm vào dòng giữa, nó đang được kiểm tra.

Rõ ràng là tôi đang thiếu thứ gì đó ở đây :) Hãy nhớ khi tôi bấm dài dòng (contextMenu mở), mọi thứ đều hoạt động tốt.

Đây là người biết lắng nghe:

lv.setOnItemClickListener(new OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle); 

       if (!markedItem.isChecked()) { 
        markedItem.setChecked(true); 
       } else { 
        markedItem.setChecked(false); 
       } 

      } 
     }); 

Đánh giá cao bất kỳ sự giúp đỡ!

Hãy cho tôi biết Nếu bạn cần tôi đăng thêm mã.

Cảm ơn bạn!

btw, Nếu tôi bấm vào nhiều hơn một ... Đảng tiếp tục ... không có thứ tự rõ ràng ...

EDIT: mã Adaptor

public class ImageCursorAdapter extends SimpleCursorAdapter { 

    private Cursor c; 
    private Context context; 

    private String url; 
    private TextView bUrl; 

    public ImageCursorAdapter(Context context, int layout, Cursor c, 
      String[] from, int[] to) { 
     super(context, layout, c, from, to); 
     this.c = c; 
     this.context = context; 
    } 

    public View getView(int pos, View inView, ViewGroup parent) { 
     View v = inView; 
     if (v == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = inflater.inflate(R.layout.image_list, null); 
     } 

     this.c.moveToPosition(pos); 

     final TextView bTitle = (TextView) v.findViewById(R.id.btitle); 
     String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE)); 


     byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON)); 

     if (favicon != null) { 
      ImageView iv = (ImageView) v.findViewById(R.id.bimage); 
      iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length)); 
     } 
     bTitle.setText(bookmark); 

     return (v); 
    } 
} 
+0

Hiển thị cho chúng tôi bộ chuyển đổi – Falmarri

+0

câu hỏi đã chỉnh sửa của bạn. Cảm ơn. –

+0

bạn có đang ghi lại giá trị vị trí trong trình nghe không? Bạn có người nghe nào khác không? – Jim

Trả lời

11

Mayra là đúng - vấn đề phải làm theo cách mà ListView đang sử dụng lại lượt xem của bạn. Nó không phải là nếu có 9 trường hợp của đối tượng CheckedTextView, một đối tượng trên mỗi lượt xem. Thay vào đó, có một cái duy nhất được tái sử dụng trong tất cả các hàng. Vì vậy, bạn không thể dựa vào đối tượng CheckedTextView để giữ trạng thái cho dù một mục được chọn. Bạn sẽ cần một số cấu trúc dữ liệu bổ sung để giữ cho dù liên tiếp đưa ra được kiểm tra Ví dụ,

ArrayList<Boolean> checkedStates = new ArrayList<Boolean>(); 

Trong trường hợp yếu tố ith là đúng khi và chỉ khi hàng ith nên được kiểm tra. Sau đó, trong vòng itemClickListener của bạn:

lv.setOnItemClickListener(new OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      boolean currentlyChecked = checkedStates.get(position); 
      checkedStates.set(position, !currentlyChecked); 
      // Refresh the list 
     } 
    }); 

Sau đó trong mã xem của bạn:

public View getView(int pos, View inView, ViewGroup parent) { 
    View v = inView; 
    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(R.layout.image_list, null); 
    } 

    this.c.moveToPosition(pos); 

    final TextView bTitle = (TextView) v.findViewById(R.id.btitle); 
    String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE)); 


    byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON)); 

    if (favicon != null) { 
     ImageView iv = (ImageView) v.findViewById(R.id.bimage); 
     iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length)); 
    } 
    bTitle.setText(bookmark); 


    // Change the state of the checkbox to match that of the row's checked state. 
    // This check box item is reused for every row, so we need to reset its state each 
    // time the row is rendered. 
    CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle); 
    markedItem.setChecked(checkedStates.get(pos)); 


    return (v); 
} 

này nên giải quyết vấn đề của bạn. Một cách tiếp cận khác là di chuyển lôgic cho dù hàng được kiểm tra hay không vào đối tượng miền mà hàng đại diện. Đó sẽ là sở thích của tôi.

+0

Cảm ơn bạn đã trả lời! Cố gắng gợi ý của bạn và không có vấn đề gì tôi đã làm tôi có một lực lượng đóng cho "IndexOutOfBoundsExeption". Bất kỳ ý tưởng nào? –

+0

Bạn cần tại một số điểm thêm các mục nhập ban đầu vào ArrayList. Khi bạn biết có bao nhiêu mục, ví dụ: 'for (int i = 0; i I82Much

+0

Ok cảm ơn bạn rất nhiều. sẽ cố gắng này! –

Các vấn đề liên quan