可见性从 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
均已正确选中和取消选中。
更新:还尝试了 notifyDataSetChanged
、holder.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;
}
我希望这可以帮助其他遇到类似问题的人。
我的 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
均已正确选中和取消选中。
更新:还尝试了 notifyDataSetChanged
、holder.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;
}
我希望这可以帮助其他遇到类似问题的人。