可以在没有交互的情况下调用onCheckedChanged方法吗?

时间:2012-05-18 18:41:24

标签: android oncheckedchanged

我有一个自定义ListView,其中点击一个项会触发一个新的ActivityListView的每一行都有CheckBoxTextView

这是我的自定义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吗?

4 个答案:

答案 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()的监听器(然后您可以重置监听器)像你一样做)。就像杰森罗宾逊建议的那样。