如何检查ListView中的所有复选框

时间:2013-12-10 08:53:57

标签: android android-listview android-checkbox

我有一个列表,其中每行包含一个复选框和一个textview,我也有一个按钮,应该检查/取消选中列表中的所有复选框,但是,我无法使用复选框OUTSIDE来实现这一点。屏幕,只有可见的一个。如果我理解得很好,那就是因为屏幕外的项目不存在,它们会在滚动时被回收以创建新行,在尝试检查/访问屏幕外的复选框时会导致空指针/退出索引错误。 / p>

我用谷歌搜索解决方案但到目前为止没有任何工作。

我该如何解决这个问题?

这是适配器:

public class AlumnoArrayAdapter<T> extends BaseAdapter{

    Context mContext;
    LayoutInflater mInflater;
    ArrayList<T> mList;
    ArrayList<Alumno> alumno;
    boolean verEstadisticas;
    SparseBooleanArray mSparseBooleanArray;

    public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) {

        //TODO Auto-generated constructor stub
        this.alumno = alumno;
        this.verEstadisticas = verEstadisticas;

        this.mContext = context;

        mInflater = LayoutInflater.from(mContext);
        mSparseBooleanArray = new SparseBooleanArray();
        mList = new ArrayList<T>();
        this.mList = list;
    }

    public ArrayList<T> getCheckedItems() {
        ArrayList<T> mTempArry = new ArrayList<T>();

        for(int i=0;i<mList.size();i++) {
            if(mSparseBooleanArray.get(i)) {
                mTempArry.add(mList.get(i));
            }
        }
        return mTempArry;
    }

    public int getCount() {
        return mList.size();
    }

    public Object getItem(int position) {
        return mList.get(position);
    }

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

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

        if(convertView == null) {
            convertView = mInflater.inflate(R.layout.row, null);
        }

        TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
        tvTitle.setText(mList.get(position).toString());

        CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable);
        mCheckBox.setTag((Integer) position);
        mCheckBox.setChecked(mSparseBooleanArray.get(position));
        mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);

        if(verEstadisticas){
            mCheckBox.setVisibility(View.GONE);
        }   

        mCheckBox.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                CheckBox cb = (CheckBox) v;
                Integer position = (Integer) cb.getTag();
                alumno.get(position).setChecked(cb.isChecked());                
            }
        });     

        return convertView;
    }

    OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {            
            mSparseBooleanArray.put((Integer) buttonView.getTag(), isChecked);          
        }
    };
}

如果需要更多代码,请告诉我们。

感谢任何可能的帮助。

提前致谢!

编辑:有一个解决方案!,修改后的适配器:

public class AlumnoArrayAdapter<T> extends BaseAdapter{

    Context mContext;
    LayoutInflater mInflater;
    ArrayList<T> mList;
    ArrayList<Alumno> alumno;
    boolean verEstadisticas;
    SparseBooleanArray mSparseBooleanArray;

    boolean checarTodo = false;

    public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) {

        //TODO Auto-generated constructor stub
        this.alumno = alumno;
        this.verEstadisticas = verEstadisticas;

        this.mContext = context;

        mInflater = LayoutInflater.from(mContext);
        mSparseBooleanArray = new SparseBooleanArray();
        mList = new ArrayList<T>();
        this.mList = list;
    }

    public ArrayList<T> getCheckedItems() {
        ArrayList<T> mTempArry = new ArrayList<T>();

        for(int i=0;i<mList.size();i++) {
            if(mSparseBooleanArray.get(i)) {
                mTempArry.add(mList.get(i));
            }
        }
        return mTempArry;
    }

    public int getCount() {
        return mList.size();
    }

    public Object getItem(int position) {
        return mList.get(position);
    }

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

    public void checkAll(){
        for(int x = 0; x < alumno.size(); x++){
            alumno.get(x).setChecked(!alumno.get(x).isChecked());
        }
    }

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

        if(convertView == null) {
            convertView = mInflater.inflate(R.layout.row, null);
        }

        TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
        tvTitle.setText(mList.get(position).toString());

        CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable);
        mCheckBox.setTag((Integer) position);
        mCheckBox.setChecked(alumno.get(position).isChecked());

        if(verEstadisticas){
            mCheckBox.setVisibility(View.GONE);
        }   

        mCheckBox.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                CheckBox cb = (CheckBox) v;
                //Alumno Alumno = (Alumno) cb.getTag();
                Integer position = (Integer) cb.getTag();
                alumno.get(position).setChecked(cb.isChecked());                
            }
        });     

        return convertView;
    }


}

4 个答案:

答案 0 :(得分:3)

您可以尝试以下方法:

  1. 在适配器中添加一个布尔属性,并设置相同的方法。
  2. 点击按钮,查看所有复选框。调用adapter方法设置boolean值。并调用notifyDataSetChanged,这应该使列表视图无效并重绘。
  3. 在重绘过程​​中,调用适配器的getView方法。因此,在此方法中检查布尔值是设置为true还是false,并相应地选中或取消选中复选框。
  4. 我希望这一步有所帮助。

答案 1 :(得分:1)

您需要操纵基础数据结构中的“已检查”信息。正如您所说,GUI对象仅用于表示底层数据的可视化表单。使用GUI对象作为保存应用程序状态信息的唯一方法是很诱人的,但不是一个好主意。

答案 2 :(得分:1)

检查此代码。尝试采用适配器。它不一样。但很少有修改肯定会奏效。

class CustomAdapter extends ArrayAdapter<ContactPerson>{
        private ArrayList<ContactPerson> contactList;

        public CustomAdapter(Context context, int textViewResourceId,
                ArrayList<ContactPerson> contactList) {
            super(context, textViewResourceId, contactList);
            // TODO Auto-generated constructor stub
            this.contactList = new ArrayList<ContactPerson>();
            this.contactList.addAll(contactList);
        }

        private class ViewHolder{
            TextView ContactName;
            CheckBox contactCheck;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub

            ViewHolder holder = null;
            Log.v("Convert View", String.valueOf(position));

            if(convertView==null){
                LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

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

                holder = new ViewHolder();
                holder.ContactName = (TextView) convertView.findViewById(R.id.contact_name);
                holder.contactCheck = (CheckBox) convertView.findViewById(R.id.contact_check);

                convertView.setTag(holder);

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

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        CheckBox cb = (CheckBox) v;
                        ContactPerson contact = (ContactPerson) cb.getTag();
//                      Log.i("clicked users", contact.getName());

                        contact.setSelected(cb.isChecked());
                    }
                });
            }
            else{
                holder = (ViewHolder) convertView.getTag();
            }

            ContactPerson contacts = contactList.get(position);
            holder.ContactName.setText("("+contacts.getName()+")");
            holder.contactCheck.setChecked(contacts.isSelected());
            holder.contactCheck.setTag(contacts);
            holder.ContactName.setText(contacts.getName());
            return convertView;
        }
    }



    private void checkButtonClick(){
        Button nextButton = (Button) findViewById(R.id.selected_done);
        nextButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                StringBuffer display = new StringBuffer();
                display.append("the selected contacts are");

                ArrayList<ContactPerson> finalContactList = contactAdapter.contactList;
                for(int i=0;i<finalContactList.size();i++){
                    ContactPerson selected = finalContactList.get(i);
                    if(selected.isSelected()){
                        display.append("\n"+selected.getName()+"\t"+selected.getPhoneNumber());
                    }
                }
                Toast.makeText(getApplicationContext(), display, Toast.LENGTH_LONG).show();
            }
        });
    }

答案 3 :(得分:1)

我会使用内置的listview函数来标记已检查的项目:setItemChecked,并结合行的自定义可检查视图。有关创建可检查视图的完美演练(有关处理复选框子项的部分),请参阅Here。为了完整起见,这是一个可检查视图的示例:

public class ExampleListItemView extends RelativeLayout implements Checkable {

    private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };

    public ExampleListItemView(Context context) {
            super(context);
    }

    public ExampleListItemView(Context context, AttributeSet attrs) {
            super(context, attrs);
    }

    public ExampleListItemView(Context context, AttributeSet attrs,
                    int defStyle) {
            super(context, attrs, defStyle);
    }

    TextView txtExample;
    CheckBox cbExample;

    private boolean isChecked = false;

    @Override
    protected void onFinishInflate() {
            super.onFinishInflate();        
            txtExample = (TextView) findViewById(R.id.txtExample);
            cbExample = (CheckBox) findViewById(R.id.cbExample);
            isChecked = false;
    }

    public void setText(String text){
            txtExample.setText(text);
    }

    @Override
    public boolean isChecked() {
            return isChecked;
    }

    @Override
    public void setChecked(boolean checked) {                

            if (isChecked != checked) {
                    cbExample.setChecked(checked);
                    isChecked = checked;
                    refreshDrawableState();
            }
    }

    @Override
    public void toggle() {
            setChecked(!isChecked);
    }

    @Override
    public int[] onCreateDrawableState(int extraSpace) {
            final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
            if (isChecked()) {
                    mergeDrawableStates(drawableState, CHECKED_STATE_SET);
            }
            return drawableState;
    }

相关的xml布局:

<?xml version="1.0" encoding="utf-8"?>
<com.example.ExampleListItemView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ndroid:addStatesFromChildren="true" >

    <CheckBox android:id="@+id/cbExample" />

    <TextView
        android:id="@+id/txtExample"
        android:layout_toRightOf="@id/cbExample" />

</com.example.ExampleListItemView>

然后你会得到类似的东西:

for(int i = 0; i < adapter.getCount(); i++){
    listView.setItemChecked(i, true);
}

SparseBooleanArray checked = listView.getCheckedItemPositions();