我有一个自定义ListView
,其中点击一个项会触发一个新的Activity
。
ListView
的每一行都有CheckBox
和TextView
。
这是我的自定义getView
中的ListView
方法:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.puzzles_row, null);
}
ListedPuzzle lp = items.get(position);
if (lp != null) {
TextView title = (TextView) v.findViewById(R.id.listTitles);
title.setText(lp.getTitle());
CheckBox star = (CheckBox) v.findViewById(R.id.star_listed);
star.setChecked(lp.isStarred());
star.setTag(new Integer(position));
star.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Integer realPosition = (Integer) buttonView.getTag();
ListedPuzzle obj = items.get(realPosition);
starListedPuzzle(obj.getId(), isChecked);
}
});
}
return v;
}
从另一个Activty返回时调用onCheckedChanged
,没有可能的用户交互来实际检查任何内容。
重点是过去工作正常,并没有真正改变任何东西。我read这是一个错误但不能真正相信它。
它始终在ListView
的相同两个项目上调用该方法。他们可以以某种方式设置为checkedChange=true
吗?
答案 0 :(得分:9)
我感觉onRestoreInstanceState
方法正在发生这种情况。 Android会在暂停和恢复活动时自动处理恢复活动中大多数View
的状态。恢复时,听起来它正在恢复CheckBox
对象的已检查状态,这会触发onCheckedChanged
。尝试在Activity
中执行此操作,如果这样可以解决您的问题,请告诉我们:
private boolean mRestoringInstanceState;
@Override
protected void onRestoreInstanceState( Bundle savedInstanceState ) {
mRestoringInstanceState = true;
super.onRestoreInstanceState( savedInstanceState );
mRestoringInstanceState = false;
}
然后更改您的onCheckChanged
方法:
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(!mRestoringInstanceState) {
Integer realPosition = (Integer) buttonView.getTag();
ListedPuzzle obj = items.get(realPosition);
starListedPuzzle(obj.getId(), isChecked);
}
}
编辑:可能更好/更简单的解决方案是在onResume
方法中分配侦听器,因为它会在onRestoreInstanceState
之后调用。请注意,如果使用此解决方案,则不会实现上述任何一项:
@Override
protected void onResume() {
super.onResume();
CheckBox star = (CheckBox) v.findViewById(R.id.star_listed);
star.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// onCheckedChanged implementation
}
});
}
Edit2:刚刚意识到你在Adapter
中这样做了。这可能与onRestoreInstanceState
无关,但我认为我看到了问题。您正在View
重新使用Adapter
,这很好,但您在设置侦听器之前要设置star
进行检查。问题是star
上次通过getView
方法时已经有一个监听器。在致电star.setChecked()
之前,请致电star.setOnCheckedChangedListener(null)
,看看是否能解决您的问题。
答案 1 :(得分:6)
我也使用自定义适配器遇到了这个问题。
我发现检查按钮是否已解决问题:
OnCheckedChangeListener ccl = new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(buttonView.isShown())
{
}
}
};
答案 2 :(得分:3)
可以在片段
中的onRestoreInstanceState上调用它您可以使用
禁用它android:saveEnabled="false"
在Checkbox的布局定义
上答案 3 :(得分:1)
检查侦听器中的堆栈跟踪
public void onCheckedChanged(CompoundButton buttonView, isChecked) {
<breakpoint here>
}
如果您在堆栈跟踪中看到onRestoreInstanceState()
,则可以在布局中使用它:
<CheckBox
...
android:saveEnabled="false" />
......如此处所示: Android CheckBox -- Restoring State After Screen Rotation
或强>
如果您看到star.setChecked()
是在堆栈跟踪中从您getView()
调用的那个,那么只需在star.setOnCheckedChangedListener(null)
之前移除star.setChecked()
的监听器(然后您可以重置监听器)像你一样做)。就像杰森罗宾逊建议的那样。