2012-07-05 33 views
25


Tôi có gì: chế độ xem danh sách tùy chỉnh với Văn bản và hộp kiểm. Khi cuộn Chế độ xem danh sách tùy chỉnh, giá trị hộp kiểm thay đổi


Sự cố: Giả sử màn hình của tôi chỉ có thể hiển thị 6 mục danh sách vào thời điểm và các mục khác không hiển thị. Vì vậy, tôi đã kiểm tra phần tử đầu tiên trong danh sách (mục tại vị trí 0). Tôi cuộn xuống để xem tất cả danh sách của tôi, khi tôi cuộn lên ở phần tử đầu tiên (mục tại vị trí 0), hộp kiểm được chọn chính xác. Tuyệt quá! Nhưng bây giờ có các mục mới được kiểm tra quá, ví dụ như mục ở vị trí 8 (vì khi tôi cuộn danh sách (đối với theRycicling) nó trở thành mục mới ở vị trí 0..remember màn hình của tôi chỉ hiển thị 7 phần tử tại thời điểm). Và nó trở thành kiểm tra, nhưng tôi chưa bao giờ kiểm tra nó!

Câu hỏi: Làm thế nào tôi có thể tránh được sự cố này? Tôi không muốn hộp kiểm mà tôi không nhấp vào thay đổi trạng thái của họ.
Dưới bộ chuyển đổi của tôi cho ListView với chức năng getView nơi tôi đã triển khai setOnCheckedChangeListener:

public class NewQAAdapterSelectFriends extends BaseAdapter { 
private LayoutInflater mInflater; 
private Person[] data; 


public NewQAAdapterSelectFriends(Context context) { 
    mInflater = LayoutInflater.from(context); 
} 

public void setData(Person[] data) { 
    this.data = data; 
} 

@Override 
public int getCount() { 
    return data.length; 
} 

@Override 
public Object getItem(int item) { 
    return data[item]; 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 



@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.item_select_friends, null); 
     final ViewHolder viewHolder = new ViewHolder(); 
     viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName); 
     viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname); 
     viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage); 
     viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox); 
     convertView.setTag(viewHolder); 
     viewHolder.nameText.setTag(viewHolder.nameText); 
     viewHolder.nameText.setTag(viewHolder.surnameText); 
     viewHolder.contactImage.setTag(data[position]); 
     viewHolder.checkBox.setOnCheckedChangeListener(
       new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 
         Person element = (Person) viewHolder.checkBox.getTag(); 

         if(isChecked){ 
          element.setCheck(buttonView.isChecked()); 
          //data[position].setCheck(true); //this is equivalent to previous line 

         } 
         else{ 
          //to-do 

         } 

        } 
       }); 
     viewHolder.checkBox.setTag(data[position]); 

    } else { 


    } 

    ViewHolder holder = (ViewHolder) convertView.getTag(); 
    holder.nameText.setText(data[position].getName()); 
    holder.surnameText.setText(data[position].getSurname()); 
    holder.contactImage.setImageResource(data[position].getPhotoRes()); 
    holder.contactImage.setScaleType(ScaleType.FIT_XY); 
    holder.checkBox.setChecked(data[position].isCheck()); 
    return convertView; 
} 

static class ViewHolder { 
    TextView nameText; 
    TextView surnameText; 
    ImageView contactImage; 
    CheckBox checkBox; 
} 
} 

Cảm ơn câu trả lời :)

EDIT: Với đề nghị tôi thay đổi getView tôi như bên dưới:

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    final ViewHolder viewHolder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.item_select_friends, null); 
     viewHolder=new ViewHolder(); 
     viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName); 
     viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname); 
     viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage); 
     viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox); 

     convertView.setTag(viewHolder); 

     viewHolder.nameText.setTag(viewHolder.nameText); 
     viewHolder.nameText.setTag(viewHolder.surnameText); 
     viewHolder.contactImage.setTag(data[position]); 
     viewHolder.checkBox.setChecked(data[position].isCheck()); 
     viewHolder.checkBox.setOnClickListener(new OnClickListener() { 

      public void onClick(View arg0) { 

       if(viewHolder.checkBox.isChecked()==true) 
        data[position].setCheck(true); 
       else 
        data[position].setCheck(false); 
      } 
     }); 

    } 
    else{ 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 

    viewHolder.nameText.setText(data[position].getName()); 
    viewHolder.surnameText.setText(data[position].getSurname()); 
    viewHolder.contactImage.setImageResource(data[position].getPhotoRes()); 
    viewHolder.contactImage.setScaleType(ScaleType.FIT_XY); 
    viewHolder.checkBox.setChecked(data[position].isCheck()); 
    return convertView; 
} 

SITUATION SAU EDIT: Bây giờ, nếu tôi kiểm tra các mục ban đầu được hiển thị trên màn hình và sau đó tôi scrool danh sách, giá trị của họ được lưu một cách chính xác. Nhưng khi tôi di chuyển danh sách và ví dụ tôi muốn kiểm tra các hộp kiểm tra cây cuối cùng của danh sách của tôi sau đó sau khi tôi di chuyển chúng trở thành uncheked .... NHƯNG TẠI SAO ??????

SOLVED: Tôi giải quyết vấn đề của tôi về getView với mã này:

public class NewQAAdapterSelectFriends extends BaseAdapter { 
private LayoutInflater mInflater; 
private Person[] data; 
boolean[] checkBoxState; 
ViewHolder viewHolder; 

public NewQAAdapterSelectFriends(Context context) { 
    mInflater = LayoutInflater.from(context); 
} 


public void setData(Person[] data) { 
    this.data = data; 
    checkBoxState=new boolean[data.length]; 
} 

@Override 
public int getCount() { 
    return data.length; 
} 

@Override 
public Object getItem(int item) { 
    return data[item]; 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 



@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.item_select_friends, null); 
     viewHolder=new ViewHolder(); 

     viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName); 
     viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname); 
     viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage); 
     viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox); 

     convertView.setTag(viewHolder); 

    } 
    else{ 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 

    viewHolder.nameText.setText(data[position].getName()); 
    viewHolder.surnameText.setText(data[position].getSurname()); 
    viewHolder.contactImage.setImageResource(data[position].getPhotoRes()); 
    viewHolder.contactImage.setScaleType(ScaleType.FIT_XY); 
    viewHolder.checkBox.setChecked(checkBoxState[position]); 
    viewHolder.checkBox.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) { 
       if(((CheckBox)v).isChecked()){ 
        checkBoxState[position]=true; 
        data[position].setCheck(true); 
       }else{ 
        checkBoxState[position]=false; 
        data[position].setCheck(false); 
       } 
      } 
     }); 
    return convertView; 
} 


static class ViewHolder { 
    TextView nameText; 
    TextView surnameText; 
    ImageView contactImage; 
    CheckBox checkBox; 
} 

}

Tôi đã thấy hướng dẫn này để làm getView tôi: http://androidcocktail.blogspot.it/2012/04/adding-checkboxes-to-custom-listview-in.html

+0

giải pháp vĩ đại, làm việc của nó đối với tôi – Ravikumar11

+0

Chỉ một câu hỏi? Dữ liệu Person [] là gì? Ý tôi là nó trông như thế nào? – Josef

+0

Giải pháp duy nhất có hiệu quả đối với tôi. –

Trả lời

1

Bạn không bao gồm trường hợp convertView! = null, đây là những gì sẽ xảy ra khi cuộn lên và xuống. Bạn nên thực hiện một cách để tái chế các convertView (tốt hơn) hoặc chỉ cần bỏ qua nó và cung cấp cho một tươi xem lại trong trường hợp này quá (tồi tệ hơn).

+0

Cảm ơn, nhưng Làm thế nào tôi có thể làm điều này? –

2

Bạn đang đặt thẻ của hộp kiểm chỉ khi chuyển đổi là rỗng. Điều này chỉ xảy ra cho màn hình đầu tiên của các bản ghi. Khi người dùng cuộn xuống, các bản chuyển đổi trước đó được tái chế. Vì vậy, các hộp kiểm của bạn có các mục dữ liệu cũ hơn làm thẻ của chúng.

thay đổi người nghe kiểm tra của bạn sẽ trông như thế này:

new CompoundButton.OnCheckedChangeListener() 
{ 
    @Override 
    public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) 
    { 
     Person element = (Person) viewHolder.checkBox.getTag(); 

     data[position].setCheck(isChecked); 

     if(isChecked) 
     { 
      // do your stuff 
     } 
     else 
     { 
      //to-do 
     } 

    } 
} 
+0

Cảm ơn bạn đã trả lời, nhưng tôi không làm việc. Bây giờ nếu tôi kiểm tra một số chekbox khi tôi di chuyển danh sách tôi bị mất các thay đổi và mỗi hộp kiểm là uncheked !!! Tôi sẽ cố gắng thêm cũng: if (isChecked) dữ liệu [position] .setChecked (true) dữ liệu khác [position] .setChecked (false) ... Làm thế nào tôi có thể làm ??? –

+0

DON "T sử dụng onCheckedChanged, sử dụng onClick thay vào đó, làm việc cho tôi. – RRTW

0

kiểm tra mã này

public class NewQAAdapterSelectFriends extends BaseAdapter { 
private LayoutInflater mInflater; 
private Person[] data; 
ArrayList<String> checkedItem=new ArrayList<String>(); 

public NewQAAdapterSelectFriends(Context context) { 
    mInflater = LayoutInflater.from(context); 
} 

public void setData(Person[] data) { 
    this.data = data; 
} 

@Override 
public int getCount() { 
    return data.length; 
} 

@Override 
public Object getItem(int item) { 
    return data[item]; 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 



@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.item_select_friends, null); 
     final ViewHolder viewHolder = new ViewHolder(); 
     viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName); 
     viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname); 
     viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage); 
     viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox); 
     convertView.setTag(viewHolder); 
     viewHolder.nameText.setTag(viewHolder.nameText); 
     viewHolder.nameText.setTag(viewHolder.surnameText); 
     viewHolder.contactImage.setTag(data[position]); 
     viewHolder.checkBox.setOnCheckedChangeListener(
       new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 
         Person element = (Person) viewHolder.checkBox.getTag(); 

         if(isChecked){ 
          getCheckList(data[position],isChecked); 
         } 
         else{ 
          getCheckList(data[position],isChecked);  
         } 

        } 
       }); 
     viewHolder.checkBox.setTag(data[position]); 
    } 
    ViewHolder holder = (ViewHolder) convertView.getTag(); 
    holder.nameText.setText(data[position].getName()); 
    holder.surnameText.setText(data[position].getSurname()); 
    holder.contactImage.setImageResource(data[position].getPhotoRes()); 
    holder.contactImage.setScaleType(ScaleType.FIT_XY); 
    if(checkedItem != null && checkedItem.contains(data[position])){ 
     viewHolder.checkBox.setChecked(true); 
    }else 
    { 
     viewHolder.checkBox.setChecked(false); 
    } 
    return convertView; 
} 

static class ViewHolder { 
    TextView nameText; 
    TextView surnameText; 
    ImageView contactImage; 
    CheckBox checkBox; 
} 
public void getCheckList(String value,boolean status){ 
     if(!checkedItem.contains(value) && status) 
     { 
      checkedItem.add(value); 
     } 
     if(checkedItem.contains(value) && !status) 
     { 
      checkedItem.remove(value); 
     } 
    } 
} 
+0

tôi cố gắng giải pháp của bạn nhưng khi tôi bấm vào checkBoxs và sau đó di chuyển các chekboxs trở nên tất cả uncheched .... tại sao ??? –

+0

rằng logic làm việc cho tôi. kiểm tra giá trị của checkedItem hoặc gửi mã thay đổi của bạn logic này được áp dụng. –

+0

Hi, tôi thay đổi mã của tôi là câu trả lời của bạn. tôi đã từng cùng mã nhưng hộp bị mất giá trị của họ :(.. –

4

Kiểm tra mã dưới đây -

public View getView(int position, View convertView, ViewGroup parent){ 
      View view = convertView; 
      ViewHolder holder = new ViewHolder(); 

      if(view == null){ 

       view = inflater.inflate(R.layout.list_callcycle_blue, null);     
       holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container); 
       holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc); 
       holder.cb = (CheckBox) view.findViewById(R.id.cb_store); 

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

      final Object data = getItem(position); 
      holder.lblLabel.setText(data.getDescription()); 

      holder.cb.setTag(position); 
      holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

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

        int position = (Integer) buttonView.getTag(); 
        objects.get(position).setChecked(buttonView.isChecked()); 
       } 
      }); 
      holder.cb.setChecked(isChecked(position)); 

      return view; 
     } 

Luôn giữ trong tâm trí, thay đổi sử dụng holder.cb.setOnCheckedChangeListener()tức là bất kỳ người nghe trước khi nó thiết lập dữ liệu, trong trường hợp của chúng tôi nó là holder.cb.setChecked()

Lý do: Khi chúng ta di chuyển, listview sẽ tái chế các quan điểm, vì vậy nếu setchecked được sử dụng trước khi người nghe sau đó nó sẽ lấy giá trị trên cơ sở nghe cũ . Và nếu chúng ta đặt nó sau khi nghe, sau đó nó sẽ mất giá trị mới nhất

+1

đã giúp chủ yếu cho cách bạn giải thích lý do cho việc đưa giá trị thiết lập sau khi bộ listener –

5

tôi giải quyết vấn đề của tôi chỉ cần thay đổi "setOnCheckedChangeListener" thành "setOnClickListener"

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

    ViewHolder holder; 

    if (convertView == null) { 

     CheckBox cbItemChecklist = new CheckBox(context); 

     holder = new ViewHolder(); 
     holder.cbItemChecklist = cbItemChecklist; 

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

    final ItemChecklist itemChecklist = itensChecklist.get(position); 

    holder.cbItemChecklist.setText(itemChecklist 
      .getDescricaoItemChecklist()); 
    holder.cbItemChecklist.setChecked(itemChecklist.isChecked()); 
    holder.cbItemChecklist 
      .setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        if(itemChecklist.isChecked()){ 
         itemChecklist.setChecked(false); 
        } else { 
         itemChecklist.setChecked(true);       
        } 


       } 
      }); 
    return convertView; 
} 
+0

Hoàn hảo ..... cảm ơn .... :) –

0

tôi có một lựa chọn tốt cho một CheckBox. Bạn có thể sử dụng android:state_activated="true" cho các hàng ListView của mình. Nó không mất trạng thái của nó và không đòi hỏi nhiều mã.

Dưới đây là làm thế nào để làm việc

  • tạo active_row.xml trong thư mục drawable của bạn


<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_activated="true"   
      android:drawable="@android:color/darker_gray"/> 
</selector> 
  • Đặt nền của bố trí Row của bạn như android:background="@drawable/active_row.xml"
  • Và cuối cùng thêm video này vào ListView android:choiceMode="multipleChoice"

Bạn có thể kiểm tra nhà nước về mỗi hàng như

View v; 

LinearLayout yourRowLayout; 
for (int i = 0; i < yourListView.getChildCount(); i++) { 
v = yourListView.getChildAt(i); 
yourRowLayout = (LinearLayout) v.findViewById(R.id. yourRowLayout); 
if(yourRowLayout.isActivated()){.... } } 
0

Bạn cần cập nhật các bộ chuyển đổi để giữ lại giá trị của checkbox

holder.chk.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       CheckBox c = (CheckBox)v.findViewById(R.id.chkID); 
       Boolean chk = c.isChecked(); 
       Integer pos = (Integer)v.getTag(); 
       itemList.get(pos).setChk(chk); 

      } 
     }); 

Để biết thêm giúp bạn có thể tham khảo bài này trong Retain Checkbox value

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