【问题标题】:checkboxes not checked properly. Android复选框未正确检查。安卓
【发布时间】:2013-11-27 07:27:23
【问题描述】:

我已经为 listview 实现了一个 cutomAdapter。我在其中实现了一些复选框。问题是当我选中第一个位置的复选框时,会选中其他一些复选框。

这是我的适配器...

    public class AScustomadapter extends BaseAdapter {

private ArrayList<String> mListItems;
private LayoutInflater mLayoutInflater;
int i = 0;

public AScustomadapter(Context context, ArrayList<String> arrayList){
    mListItems = arrayList;
    //get the layout inflater
    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    return mListItems.size();
}

@Override
public Object getItem(int i) {
    return null;
}

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

@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
    // create a ViewHolder reference
    ViewHolder holder;

    //check to see if the reused view is null or not, if is not null then reuse it
    if (view == null) {
        holder = new ViewHolder();

        view = mLayoutInflater.inflate(R.layout.list_item, null);
        holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);

        holder.b1 = (Button) view.findViewById(R.id.button1);
        holder.cb1 = (CheckBox) view.findViewById(R.id.checkBox1);

        // the setTag is used to store the data within this view
        view.setTag(holder);
    } else {
        // the getTag returns the viewHolder object set as a tag to the view
        holder = (ViewHolder)view.getTag();
    }

    //get the string item from the position "position" from array list to put it on the TextView
    final String stringItem = mListItems.get(position);

    if (stringItem != null) {
        if (holder.itemName != null) {
            //set the item name on the TextView
            holder.itemName.setText(stringItem);
        }
    }

    //button
    holder.b1.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(v.getContext(), ASreviewCA.class);
            i.putExtra("sItem", stringItem);
            v.getContext().startActivity(i);
        }
    });

    //view
    view.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (position == 0) { 
            }
            Log.d("LIST", "Selected item # " + position);
        }
    });

    holder.cb1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // TODO Auto-generated method stub
            if (isChecked) {
                i++;
                Toast toast = Toast.makeText(buttonView.getContext(), String.valueOf(i), Toast.LENGTH_SHORT);
                toast.show();

            }else {
                i--;
                Toast toast = Toast.makeText(buttonView.getContext(), String.valueOf(i), Toast.LENGTH_SHORT);
                toast.show();
            }
        }
    });

    //this method must return the view corresponding to the data at the specified position.
    return view;
}
/**
 * Static class used to avoid the calling of "findViewById" every time the getView() method is called,
 * because this can impact to your application performance when your list is too big. The class is static so it
 * cache all the things inside once it's created.
 */
private static class ViewHolder {

    protected TextView itemName;
    protected Button b1;
    protected CheckBox cb1;

}

}

【问题讨论】:

  • 当你点击行xI下一行等等也改变了?
  • 滚动列表视图时会自动检查吗?
  • 实际上当我选中一个框然后取消选中它时,它会在我滚动列表视图后自动选中。

标签: android checkbox android-listview


【解决方案1】:

在 Adapter 类中维护一个 ArrayList 用于检查位置,并在 getView() 方法中检查检查位置。喜欢...

private ArrayList<Integer> checkedIndices = new ArrayList<Integer>();
.......

@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
// create a ViewHolder reference
ViewHolder holder;

//check to see if the reused view is null or not, if is not null then reuse it
if (view == null) {
    holder = new ViewHolder();

    view = mLayoutInflater.inflate(R.layout.list_item, null);
    holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);

    holder.b1 = (Button) view.findViewById(R.id.button1);
    holder.cb1 = (CheckBox) view.findViewById(R.id.checkBox1);

    // the setTag is used to store the data within this view
    view.setTag(holder);
} else {
    // the getTag returns the viewHolder object set as a tag to the view
    holder = (ViewHolder)view.getTag();
}

//get the string item from the position "position" from array list to put it on the TextView
final String stringItem = mListItems.get(position);

if (stringItem != null) {
    if (holder.itemName != null) {
        //set the item name on the TextView
        holder.itemName.setText(stringItem);
    }
}

//button
holder.b1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent i = new Intent(v.getContext(), ASreviewCA.class);
        i.putExtra("sItem", stringItem);
        v.getContext().startActivity(i);
    }
});

//view
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        if (position == 0) { 
        }
        Log.d("LIST", "Selected item # " + position);
    }
});

holder.cb1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // TODO Auto-generated method stub
        if (isChecked) {
            Toast toast = Toast.makeText(buttonView.getContext(), "Checked = "+position, Toast.LENGTH_SHORT);
            toast.show();
            checkedIndices.add(position);

        }else {
            Toast toast = Toast.makeText(buttonView.getContext(), "Unchecked = "+position, Toast.LENGTH_SHORT);
            toast.show();
            checkedIndices.remove((Integer)position));
        }
    }
});
if(checkedIndices.contains((Integer)position) {
    holder.cb1.setChecked(true);
} else {
    holder.cb1.setChecked(false);
}

//this method must return the view corresponding to the data at the specified position.
return view;

}

在 Adapter 类中编写一个方法,例如...

 public int getTotalCheckedCount() {
      return checkedIndices.size();
 }

【讨论】:

  • 我觉得你的代码一定是得到OutOfBoundsArrayIndexcheckedIndices.remove((Integer)position));,因为你必须先在列表中找到位置,然后再删除,
  • 谢谢,这很有用。我现在想在整个视图中跟踪检查项目的数量。我不希望列表的长度影响选中框的数量。你也可以为此编辑一下代码吗?非常感谢。
  • @Shayanpourvatan 不,它会抛出 NPE。你检查了吗?
  • @MohammadSohaib 您能否详细说明您的需求。我没有得到你。如果我明白了,我会编辑代码...
  • @GopalRao 如果您检查了第 20 行,则将 20 添加到正确的列表中,但是如果您想删除该列表的第 20 行,您的列表只有 1 行,您能回答我的示例吗?
【解决方案2】:

为了避免 ListView 中 CheckBoxes 的问题,您可以在开始时采用一个初始化为 false 的布尔数组,然后将在 ListView 中选中复选框的数组中的相应位置设为 true。当您在应用程序中向前和向后移动或滚动 ListView 时,这不会导致复选框的选中状态出现问题。您可以在此处查看我的示例代码:

Android checkbox multiselected issue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 2016-11-17
    • 2011-12-04
    • 2020-08-17
    相关资源
    最近更新 更多