可见性从 GONE 更改为 VISIBLE 后,复选框不会第一次检查

Checkbox doesn't check first time after visibility change from GONE to VISIBLE

我的 XML 布局中有一个 CheckBox,其可见性设置为 GONE。这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linearLayout1"
    android:layout_centerInParent="true">

    <CheckBox
        android:id="@+id/checkbox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dip"
        android:visibility="gone"
        android:checked="false"/>

    <TextView
        android:id="@+id/title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dip"
        android:layout_marginStart="10dip"
        android:layout_marginTop="10dip"
        android:layout_weight="20"
        android:ellipsize="end"
        android:maxLines="1"
        android:textAlignment="center"
        android:textColor="#000000"
        android:textSize="16sp"
        android:textStyle="bold" />
        <!--android:scrollHorizontally="true"-->
        <!--android:layout_alignParentLeft="true"-->
        <!--android:layout_alignParentStart="true"-->

    <Space
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="5" />

    <TextView
        android:id="@+id/body"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dip"
        android:layout_marginRight="8dip"
        android:layout_marginTop="10dip"
        android:layout_weight="35"
        android:ellipsize="end"
        android:maxLines="1"
        android:textAlignment="center"
        android:textColor="#000000"
        android:textSize="16sp" />
        <!--android:layout_alignParentRight="true"-->

    <ImageView
        android:id="@+id/Critical"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_weight="10"
        android:textSize="16sp" />

    <ImageView
        android:id="@+id/state"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_weight="10"
        android:textSize="16sp" />

</LinearLayout>

我在自定义适配器 setOnLongClickListener 中将 CheckBox 的可见性设置为 VISIBLE。问题发生在第一次长按时。对于列表的第一项,当我将可见性设置为 VISIBLE 然后检查其中一个 CheckBox 时,它未被检查但我的 num_selected 递增并设置为一个。这是我的 CustomAdapter getView(带注释的行):

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

            final Holder holder = new Holder();
            final View rowView;
            rowView = inflater.inflate(R.layout.list_row_layout, parent, false);

            holder.tv1 = (TextView) rowView.findViewById(R.id.title);
            holder.tv2 = (TextView) rowView.findViewById(R.id.body);
            holder.cb = (CheckBox) rowView.findViewById(R.id.checkbox1);
            holder.iv = (ImageView) rowView.findViewById(R.id.state);
            holder.i2 = (ImageView) rowView.findViewById(R.id.Critical);
            holder.tv1.setText(Titles.get(position));
            holder.tv2.setText(Bodies.get(position));
            if (isSeen.get(position))
                holder.iv.setImageResource(R.mipmap.ic_done_all_black_24dp);
            else
                holder.iv.setImageResource(R.mipmap.ic_done_black_24dp);

            if (CList.get(position)) {
                holder.i2.setImageResource(R.mipmap.ic_priority_high_black_24dp);
            }

            if(num_selected > 0)
            {
                holder.cb.setVisibility(View.VISIBLE);
            }
            else
            {
                holder.cb.setVisibility(View.GONE);
            }

            rowView.setOnLongClickListener(new View.OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {

                    if((num_selected == 1)&(holder.cb.isChecked()))
                    {
                        holder.cb.setChecked(false);
                        num_selected--;
                        isSelected = false;
                    }
                    else
                        if(holder.cb.isChecked())
                    {
                        holder.cb.setChecked(false);
                        num_selected--;
                    }
                    else {
                        holder.cb.setVisibility(View.VISIBLE);  //  this is the line that change visibility with no problem
                        holder.cb.setChecked(true);             //  it seems this line doesn't work at all! 
                        num_selected++;                         //  this line is also increment it to 1
                    }

                    return true;
                }
            });

            return rowView;
        }

似乎需要延迟检查一个CheckBox。之后,所有 CheckBox 均已正确选中和取消选中。

更新:还尝试了 notifyDataSetChangedholder.cb.invalidate();holder.cb.requestLayout();,但没有成功。另外我忘了说我的适配器是 ListAdapter.

LongClick 之前:

长按后:

无需定义复选框两次从 OnLongClickListener() 中删除此行

CheckBox c = (CheckBox) findViewById(R.id.checkbox1); 

并且在显示之后,您必须使用 notifyDatasetChanged();

通知您的适配器

在 运行 对我的代码进行一些测试后,我发现该代码使复选框在滚动时消失。 通过很少的搜索,我发现 the solution 我的问题和滚动问题。我定义了布尔数组来存储 checked/unchecked 复选框。我在我的 CustomAdapter 中将 mCheckedState 定义为 class 变量,并相应地在 setOnLongClickListener 中更新它:

private final boolean[] mCheckedState; // **New Code**

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

        final Holder holder = new Holder();
        final View rowView;
        rowView = inflater.inflate(R.layout.list_row_layout, parent, false);

        holder.tv1 = (TextView) rowView.findViewById(R.id.title);
        holder.tv2 = (TextView) rowView.findViewById(R.id.body);
        holder.cb = (CheckBox) rowView.findViewById(R.id.checkbox1);
        holder.iv = (ImageView) rowView.findViewById(R.id.state);
        holder.i2 = (ImageView) rowView.findViewById(R.id.Critical);
        holder.tv1.setText(Titles.get(position));
        holder.tv2.setText(Bodies.get(position));
        if (isSeen.get(position))
            holder.iv.setImageResource(R.mipmap.ic_done_all_black_24dp);
        else
            holder.iv.setImageResource(R.mipmap.ic_done_black_24dp);

        if (CList.get(position)) {
            holder.i2.setImageResource(R.mipmap.ic_priority_high_black_24dp);
        }

        if(num_selected > 0)
        {
            holder.cb.setVisibility(View.VISIBLE);
        }
        else
        {
            holder.cb.setVisibility(View.GONE);
        }

        rowView.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {

                if((num_selected == 1)&(holder.cb.isChecked()))
                {
                    mCheckedState[position] = false;   // **New Code**
                    holder.cb.setChecked(false);
                    num_selected--;
                    isSelected = false;
                    notifyDataSetChanged();   // **New Code**
                }
                else
                    if(holder.cb.isChecked())
                {
                    mCheckedState[position] = false;     // **New Code**
                    holder.cb.setChecked(false);     
                    notifyDataSetChanged();          // **New Code**
                    num_selected--;
                }
                else {
                    holder.cb.setVisibility(View.VISIBLE);  
                    notifyDataSetChanged();                 // **New Code**
                    holder.cb.setChecked(true);           
                    mCheckedState[position] = true;        // **New Code**
                    num_selected++;        
                }

                return true;
            }
        });

        holder.cb.setChecked(mCheckedState[position]);      // **New Code**

        return rowView;
    }

我希望这可以帮助其他遇到类似问题的人。