列表视图滚动时,复选框自动调用onCheckedChange?

时间:2011-05-23 17:11:28

标签: android listview checkbox

我对listview有一个问题,哪个列表项包含一个复选框。当我选中一个框并滚动列表时,复选框有时会自动调用oncheckedchange并且复选框的值会更改!

或者,当我的清单超过9或10项时,当我在第1项检查时,检查项目8或9 ???

任何人都可以告诉我,我该如何修复这个错误?

提前致谢!

list_item.xml

<ImageView
    android:layout_alignParentLeft="true"
    android:layout_width="36dip"
    android:layout_height="36dip"
    android:layout_centerVertical="true"
    android:scaleType="fitCenter"
    android:id="@+id/image_view"
    android:src="@drawable/icon" />

<TextView android:layout_toRightOf="@id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="5dip"
    android:id="@+id/text_view"
    android:lines="1"
    android:textSize="20sp"
    android:textColor="@color/white" />

<TextView android:layout_toRightOf="@id/image_view"
    android:layout_below="@id/text_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="5dip"
    android:id="@+id/text_view2"
    android:textSize="14sp"
    android:lines="1"
    android:textColor="@color/white" />          

这是适配器视图:

    public View getView(int position, View convertView, ViewGroup parent) {
        Log.e(TAG, "getView");
        ViewHolder mViewHolder;
        if (convertView == null) {
            Log.e(TAG, "Inflater is inflating...");
            convertView = mInflater.inflate(R.layout.custom_list_app, null);
            mViewHolder = new ViewHolder();
            mViewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox);
            mViewHolder.remove = convertView.findViewById(R.id.music_info);
            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (ViewHolder) convertView.getTag();
            Log.e(TAG, "Position: " + position + " CheckBox: " + mViewHolder.checkbox.isChecked());
        }   
        mViewHolder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton cb, boolean flag) {
                // TODO Auto-generated method stub
                if (flag) {
                    Log.d(TAG, "Checkbox checked");
                } else {
                    Log.d(TAG, "Checkbox un-checked");
                }
            }
        });


        return convertView;
    }

5 个答案:

答案 0 :(得分:74)

ListView回收视图类:您需要显式设置是否在getView类中选中CheckBox。所以添加一个像

这样的支票
/**
*    Ensure no other setOnCheckedChangeListener is attached before you manually
*    change its state.
*/
mViewHolder.checkbox.setOnCheckedChangeListener(null);
if(shouldBeChecked) mViewHolder.checkbox.setChecked(true);
else mViewHolder.checkbox.setChecked(false);
在致电setOnCheckedChangeListener之前

答案 1 :(得分:4)

holder.cBox.setOnCheckedChangeListener(null);
holder.cBox.setChecked(list.get(position).isChecked());
holder.tvName.setText(item.getName());

holder.cBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
    {
        if (isChecked)
        {
            list.get(position).setChecked(true);
        }
        else
        {
            list.get(position).setChecked(false);
        }
    }
});

在列表中,该项目具有一个属性,用于设置是否选中该项目。您可以使用它来设置是否选中项目,首先应设置

cBox.setOnCheckedChangeListener(null);
cBox.setChecked(list.get(position).isChecked());

然后设置真实new OnCheckedChangeListener()

我希望我的回答对您和那些查看此页面或者无法处理包含项目复选框的列表视图的人有用。

答案 2 :(得分:0)

我不确定这是不是很好。但是下面的代码解决了我的问题。即使在下面的代码中,在滚动列表时也会调用setOnCheckChangeListener()(读取错误触发)。任务是维护用户选择的项目列表。因此,当有触发器时,我首先引用我的列表,只添加一个项目(如果它尚未出现在列表中),否则我会忽略回调。

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


    MenuViewHolder menuViewHolder = null;
    MenuView item = getItem(position);


    LayoutInflater inflater = ((Activity) context).getLayoutInflater();

    convertView = inflater.inflate(R.layout.food_menu_list_layout, null);

    TextView textView = ((TextView) convertView.findViewById(R.id.menu_item_entry));
    TextView price = (TextView) convertView.findViewById(R.id.price);
    CheckBox ordered = (CheckBox) convertView.findViewById(R.id.checkBox);

    menuViewHolder = new MenuViewHolder(textView, price, ordered);

    menuViewHolder.dishName.setText(menuViewList.get(position).getItemname());
    menuViewHolder.price.setText("$" + menuViewList.get(position).getPrice());
    menuViewHolder.ordered.setChecked(menuViewList.get(position).isSelected());

    menuViewHolder.ordered.setOnCheckedChangeListener(null);


    menuViewHolder.ordered.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

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

            MenuView checkedItem = menuViewList.get(position);
            if (buttonView.isChecked()) {

                //add item only if not already added
                if (!checkedItem.isSelected()) {
                    MainActivity.menuViews.add(checkedItem);
                    checkedItem.setSelected(buttonView.isChecked());
                }       


            } else {

                //remove only if already added
                if (checkedItem.isSelected()){
                    MainActivity.menuViews.remove(checkedItem);
                    checkedItem.setSelected(buttonView.isChecked());
                }                    
            }

            ((MainActivity) context).displayCurrentSelectionAmt();
        }
    });


return convertView;

}

答案 3 :(得分:0)

其中大多数都过于复杂(但确实有效)。您要做的就是在加载视图并设置检查状态时停止触发.setChecked事件。因此,设置本地类变量isLoading,在getView开头将其设置为true,并在getView结束时将其设置为false。然后在单击侦听器中,选中isLoading

boolean isLoading;
public View getView(int position, View convertView, ViewGroup parent){
    isLoading = true;

    ...do your initialization here

    isLoading = false;
    return convertView;
}
checkview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton pckView, boolean pisChecked) {
            if(! isLoading) {
                ...do your things when the check is actually clicked
            }
        }
    });

答案 4 :(得分:0)

OnClickListener对我有同样的问题,我可以将数据发送到另一个活动

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

            @Override
            public void onClick(View v) {
                final boolean isChecked = holder.cks.isChecked();
                if (isChecked) {
                    System.out.println(position + "Checked");
                    holder.cks.setChecked(true);
                    positionArray.set(position, true);
                    DATA2="1";



                } else {
                    System.out.println(position + "unChecked");
                    holder.cks.setChecked(false);
                    positionArray.set(position, false);

                    DATA2 = "0";

                }
                DATA1=String.valueOf(position+1);

                DATA3=map.get(COL5);
                DATA4=map.get(COL6);
                DATA5=map.get(COL7);



                Intent intent = new Intent(activity, updatelicaldata.class);
                intent.putExtra("message1", DATA1);
                intent.putExtra("message2", DATA2);
                intent.putExtra("message3", DATA3);
                intent.putExtra("message4", DATA4);
                intent.putExtra("message5", DATA5);
                System.out.println("ACTIVITY IS START");

                activity.startActivity(intent);

            }
            });