Android - 更改屏幕方向后开关按钮状态保持选中

3

即使我在程序中将 checked 属性设置为 false,屏幕方向改变后 Switch 仍然保持选中状态。

以下是示例代码:

public class MainActivity extends AppCompatActivity {

    Switch sw;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sw = (Switch)findViewById(R.id.sw);
        sw.setChecked(false);

        System.out.println(sw.isChecked());
    }    
}
标签会打印“false”,但开关在界面上仍然保持选中状态。这是布局文件中开关的XML元素:
<Switch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/sw"
    android:checked="false"/>

我错过了什么?

2个回答

1
你的复选框在「方向更改(Orientation Change)」后没有被选中是因为 Android 在处理「方向更改」时会触发 Activity 方法,如下所示:
onPause -> onSave -> onStop -> onCreate -> onStart -> onResume

如果你想让 sw.setChecked(false); 在屏幕方向改变时触发,请将它放在你的 Activity 的 onResume() 函数中,像这样:
//Other Code Above, i.e. onCreate();
@Override
public void onResume(){
    super.onResume();
    // Put your code here...
    sw.setChecked(false);
}

还有其他选项可以防止根据Android文档下的配置更改重启Activity。

在某些特殊情况下,您可能希望基于一种或多种类型的配置更改绕过重新启动活动。这是通过其清单中的android:configChanges属性完成的。对于您在那里处理的任何类型的配置更改,您将收到当前活动的onConfigurationChanged(Configuration)方法的调用,而不会重新启动。但是,如果配置更改涉及任何您不处理的更改,则仍将重新启动活动,并且不会调用onConfigurationChanged(Configuration)。

最后通过onSaveInstanceState(Bundle savedInstanceState)onRestoreInstanceState(Bundle savedInstanceState)另一个选项:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  savedInstanceState.putBoolean("YourCheckBox", enable);
  super.onSaveInstanceState(savedInstanceState);
}

并使用此方法检索它:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  boolean mychkbox = savedInstanceState.getBoolean("YourCheckBox");
}

非常感谢!我知道有关生命周期的内容,但我一直在使用 onStart() 方法而不是 onResume,这让我非常疯狂!现在我正在使用第二个选项,但我认为对于我的情况,使用第一个选项更合理。 - M.Rodríguez
当然,你也可以通过第三个选项来维护用户选择。最好的部分是,根据实现方式,有几种选择可供使用。 - NSTuttle

0

更一般地说,您可能希望覆盖以下内容,以便在方向更改(和活动重新创建)时可以保留此状态。

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(SOME_BOOL_VALUE, boolVar);
}

并在onCreate中读取它,如果设置了savedInstanceState


是的,我现在也在做同样的事情,谢谢你的回答!我一直在考虑如何在不使用Bundle的情况下完成它,就像Illdapt所解释的那样,我认为这将是我的选择。 - M.Rodríguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接