Android:选中一个CheckBox会检查同一行中的所有CheckBox [英] Android: Checking one CheckBox checks all CheckBoxes in the same row

查看:53
本文介绍了Android:选中一个CheckBox会检查同一行中的所有CheckBox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序显示一个ListView,每个rowCheckBoxes编号不同.每行的最大数量CheckBoxes为3.我的应用程序如下所示:

My app shows a ListView with a different number of CheckBoxes for each row. The maxium number of CheckBoxes for a row is three. My app looks like this:

  1. 如果选中左侧的CheckBox,则应该自动选中右侧的所有CheckBoxes.
  2. 如果未选中右侧的CheckBox,则左侧的所有CheckBoxes都应自动取消选中.
  1. If the left CheckBox gets checked, all CheckBoxes on the right side should get checked automatically.
  2. If the right CheckBox gets unchecked, all CheckBoxes on the left side should get unchecked automatically.

我在这里举一个例子:
第一行中有三个CheckBoxes (cb1, cb2 and cb3). cb1在左侧,cb2在中间,cb3在右侧.

I´ll give a little example here:
There are three CheckBoxes (cb1, cb2 and cb3) in Row one. cb1 is on the left side, cb2 in the middle and cb3 on the right side.

  1. 所有CheckBoxes当前未选中.用户检查左一个(cb1).所有其他CheckBoxes (cb2 and cb3)都将被自动检查.
  2. 当前已检查所有CheckBoxes.用户取消选中右边的那个(cb3). 所有其他CheckBoxes (cb1 and cb2)都将自动取消锁定.
  1. All CheckBoxes are currently unchecked. The user checks the left one (cb1). All other CheckBoxes (cb2 and cb3) are getting automatically checked.
  2. All CheckBoxes are currently checked. The user unchecks the right one (cb3). All other CheckBoxes (cb1 and cb2) are getting automatically unckecked.

我试图用OnCheckedChangeListener解决我的问题,但出现以下消息

I tried to solve my problem with OnCheckedChangeListener, but the following message occurs

变量'Holder'是从内部类内部访问的,需要 被宣布为最终裁决."

"Variable 'Holder' is accessed from within the inner class, needs to be declared final."

我的问题:

  1. 如何解决此问题,以便不会出现消息?

  1. How to fix this, so that Message doesn´t occur?

我的解决方案在逻辑上对吗?

Is my solution logically right?

如果我的问题不清楚,请发表评论.

If my problem is not clear, pls leave a comment.

我的解决方案:

 holder.cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                 @Override
                 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                     buttonView.setChecked(isChecked);
                     //Case1: Left (cb1) gets checked -> set all other right CB´s (cb2 & cb3) checked
                     if(isChecked){
                         holder.cb2.setChecked(isChecked);  //Error Message occurs here
                         holder.cb3.setChecked(isChecked);  //Error Message occurs here
                     }
                   }
               });

            holder.cb2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    buttonView.setChecked(isChecked);
                    //Case2: Middle (cb2) gets checked -> set right CB (cb3) checked
                    if(isChecked){
                        holder.cb3.setChecked(isChecked);   //Error Message occurs here
                    }
                    //Case3: Middle (cb2) gets unchecked -> set left CB (cb1) unchecked
                    else {
                        holder.cb1.setChecked(isChecked);   //Error Message occurs here
                    }
                  }
              });

            holder.cb3.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    buttonView.setChecked(isChecked);
                    //Case4: Right (cb3) gets unchecked -> set all other left CB´s (cb1 & cb 2) unchecked
                    if(!isChecked){
                        holder.cb2.setChecked(isChecked);   //Error Message occurs here
                        holder.cb1.setChecked(isChecked);   //Error Message occurs here
                    }
                  }
              });

自定义适配器:

public class ItemListAdapter extends BaseAdapter {

private LayoutInflater inflater;
private ArrayList<Object> itemArray;
int resIdImage;
private static final int TYPE_ListElement = 0;
private static final int TYPE_DIVIDER = 1;

public ItemListAdapter(Context context, ArrayList<Object> itemArray, int resource) {
    this.itemArray = itemArray;
    this.resIdImage = resource;
    this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

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

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

@Override
public Object getItem(int position) {
    return itemArray.get(position);
}

@Override
public int getViewTypeCount() {
    // TYPE_PERSON and TYPE_DIVIDER
    return 2;
}

@Override
public int getItemViewType(int position) {
    if (getItem(position) instanceof ItemList) {
        return TYPE_ListElement;
    }

    return TYPE_DIVIDER;
}

@Override
public boolean isEnabled(int position) {
    return (getItemViewType(position) == TYPE_ListElement);
}

public class DataHolder{
    ImageView imageView;
    TextView textView;
    CheckBox cb1;
    CheckBox cb2;
    CheckBox cb3;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    DataHolder holder =  null;
    int type = getItemViewType(position);
    if (convertView == null) {
        switch (type) {
            case TYPE_ListElement:
                convertView = inflater.inflate(resIdImage, parent, false);
                holder = new DataHolder();
                holder.imageView = (ImageView) convertView.findViewById(R.id.image);
                holder.textView = (TextView) convertView.findViewById(R.id.nameLabel);
                holder.cb1 = (CheckBox) convertView.findViewById(R.id.checkbox);
                holder.cb2 = (CheckBox) convertView.findViewById(R.id.checkbox2);
                holder.cb3 = (CheckBox) convertView.findViewById(R.id.checkbox3);
                convertView.setTag(holder);
                break;
            case TYPE_DIVIDER:
                convertView = inflater.inflate(R.layout.row_header, parent, false);
                break;
        }
    }
    else {
        holder = (DataHolder)convertView.getTag();
    }

    switch (type) {
        case TYPE_ListElement:
            ItemList item = (ItemList) getItem(position);
            holder.textView.setText(item.getTitle());
            holder.imageView.setImageResource(item.resIdImage);

            int numCheckBox = item.numCheckBox;
            if(numCheckBox == 1){
               holder.cb1.setVisibility(View.VISIBLE);
               holder.cb2.setVisibility(View.GONE);
               holder.cb3.setVisibility(View.GONE);
            } else if (numCheckBox == 2){
               holder.cb1.setVisibility(View.VISIBLE);
               holder.cb2.setVisibility(View.VISIBLE);
               holder.cb3.setVisibility(View.GONE);
            } else if (numCheckBox == 3){
               holder.cb1.setVisibility(View.VISIBLE);
               holder.cb2.setVisibility(View.VISIBLE);
               holder.cb3.setVisibility(View.VISIBLE);
            }
             holder.cb1.setChecked(item.checked);
             holder.cb2.setChecked(item.checked);
             holder.cb3.setChecked(item.checked);

             holder.cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                 @Override
                 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                     buttonView.setChecked(isChecked);
                     //Case1: Left (cb1) gets checked -> set all other right CB´s (cb2 & cb3) checked
                     if(isChecked){
                         holder.cb2.setChecked(isChecked);  //Error Message occurs here
                         holder.cb3.setChecked(isChecked);  //Error Message occurs here
                     }
                 }
             });

            holder.cb2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    buttonView.setChecked(isChecked);
                    //Case2: Middle (cb2) gets checked -> set right CB (cb3) checked
                    if(isChecked){
                        holder.cb3.setChecked(isChecked);   //Error Message occurs here
                    }
                    //Case3: Middle (cb2) gets unchecked -> set left CB (cb1) unchecked
                    else {
                        holder.cb1.setChecked(isChecked);   //Error Message occurs here
                    }
                }
            });

            holder.cb3.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    buttonView.setChecked(isChecked);
                    //Case4: Right (cb3) gets unchecked -> set all other left CB´s (cb1 & cb 2) unchecked
                    if(!isChecked){
                        holder.cb2.setChecked(isChecked);   //Error Message occurs here
                        holder.cb1.setChecked(isChecked);   //Error Message occurs here
                    }
                }
            });

             break;

        case TYPE_DIVIDER:
            TextView title = (TextView)convertView.findViewById(R.id.headerTitle);
            String titleString = (String)getItem(position);
            title.setText(titleString);
            break;
    }


    return convertView;
}
}

行布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@mipmap/ic_launcher"
    android:layout_gravity="center"
    android:layout_margin="20dp"/>

<TextView
    android:id="@+id/nameLabel"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:layout_margin="20dp"
    android:text="Name"
    android:layout_weight="1"
/>

<CheckBox
    android:id="@+id/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="false"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:layout_gravity="right|center"
    android:gravity="right|center"
    />

<CheckBox
    android:id="@+id/checkbox2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="false"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:layout_gravity="right|center"
    android:gravity="right|center"
    />

<CheckBox
    android:id="@+id/checkbox3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="false"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:layout_gravity="right|center"
    android:gravity="right|center"
    />

</LinearLayout>

推荐答案

创建引用ViewHolderfinal变量,并在onCheckedChangeListener中使用它:

Create a final variable referencing you ViewHolder and use this inside you onCheckedChangeListener :

final DataHolder finalHolder = holder;

holder.cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                 buttonView.setChecked(isChecked);
                 //Case1: Left (cb1) gets checked -> set all other right CB´s (cb2 & cb3) checked
                 if(isChecked){
                     finalHolder.cb2.setChecked(isChecked);  // NO MORE ERROR
                     finalHolder.cb3.setChecked(isChecked);  //NO MORE ERROR
                 }
             }
         });

holder.cb2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                buttonView.setChecked(isChecked);
                //Case2: Middle (cb2) gets checked -> set right CB (cb3) checked
                if(isChecked){
                    finalHolder.cb3.setChecked(isChecked);   // NO MORE ERROR
                }
                //Case3: Middle (cb2) gets unchecked -> set left CB (cb1) unchecked
                else {
                    finalHolder.cb1.setChecked(isChecked);   //NO MORE ERROR
                }
            }
        });

也对cb3 onCheckedChangeListener做同样的事情.

这篇关于Android:选中一个CheckBox会检查同一行中的所有CheckBox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆