0

do_something()每当设备从纵向旋转到横向时,我都想这样做。

我已经<activity android:configChanges="orientation" >在我的清单中添加了。每当我onConfigurationChanged()旋转我的设备时都会调用它。它不会重新创建活动。

在我的onConfigurationChanged()功能中:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        do_something();
    }
    then_fire_off_the_screen_rotation_as_normal();
    // which means re-start the Activity
    // i expect it will fire off onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()
}

我的问题是,我不知道我能做什么then_fire_off_the_screen_rotation_as_normal()

我尝试过使用setRequestedOrientation(),但似乎不是用于此目的的功能:

当我传入ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, ActivityInfo.SCREEN_ORIENTATION_SENSOR, 或ActivityInfo.SCREEN_ORIENTATION_USER时,Activity 仍未重新启动。(就像不打电话一样。)

当我通过时ActivityInfo.SCREEN_ORIENTATION_NOSENSOR,方向传感器关闭。(正如它所说。)

当我通过时,ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE活动被强制关闭AndroidRuntime:NullPointerException


(具体一点:这是因为在纵向布局中以编程方式添加了片段,但在横向布局中没有。在do_something()函数中,我将删除这些片段,因为它们在横向模式中不需要。)

4

2 回答 2

4

好吧,我想这种简单的方法可以满足我的需求:

<activity android:configChanges="orientation" >。意味着 NO NEED OVERRIDE onConfigurationChanged()

onSaveInstanceState()

@Override
protected void onSaveInstanceState(Bundle outState) {
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        do_something();
    }
    super.onSaveInstanceState(outState);
}

* 确定你do_something() 之前 super.onSaveInstanceState()

(因为在我的情况下,我从 Layout 和 Activity 中删除了 Fragments。如果它在 之后super.onSaveInstanceState(),则 Layout 将已经保存到 Bundle 中。然后在 Activity 重新创建后, Fragments将被重新创建。 ###)

###我已经证明了这个现象。但是在 Activity 重新创建时如何确定 Fragment 恢复的原因是什么?只是我的猜测。如果您对此有任何想法,请回答我的另一个问题。谢谢!


嗯,对上面的方法进一步改进,解决了第一条评论中提出的问题:(还是简单的)

@Override
protected void onSaveInstanceState(Bundle outState) {
    if (isPortrait2Landscape()) {
        do_something();
    }
    super.onSaveInstanceState(outState);
}

private boolean isPortrait2Landscape() {
    return isDevicePortrait() && (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
}

isDevicePortrait()像:

private boolean isDevicePortrait() {
    return (findViewById(R.id.A_View_Only_In_Portrait) != null);
}

* 请注意,我们无法getResources().getConfiguration().orientation确定设备当前是否是纵向的。这是因为Resources对象在屏幕旋转后立即更改 - 甚至在调用之前! onSaveInstanceState()

如果您不想使用findViewById()来测试方向(出于任何原因,而且它毕竟不是那么整洁),请保留一个全局变量并通过inprivate int current_orientation;初始化它。这看起来更整洁。但是我们应该注意不要在 Activity 生命周期的任何地方更改它。current_orientation = getResources().getConfiguration().orientation;onCreate()

于 2013-03-26T16:46:37.867 回答
1
 // which means re-start the Activity
 // i expect it will fire off onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()

onPause()、onStop() 等将触发的假设是不正确的。通过使用onConfigurationChanged,您告诉 Android 不要执行这些步骤,而是您将处理在临时变量中保存有关布局的信息,然后调用InitializeUI(),然后将布局设置回您想要的方式。我将发布一个我有类似的东西的例子,并在一瞬间为我工作。

编辑:这是示例

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.main);
    Log.i("configChange", "configChange");

    String tmp = connect.getText().toString();
    boolean onTmp = on.isEnabled();
    boolean offTmp = off.isEnabled();
    boolean connTmp = reconnect.isEnabled();

    InitializeUI();

    connect.setText(tmp);
    on.setEnabled(onTmp);
    off.setEnabled(offTmp);
    reconnect.setEnabled(connTmp);
}

现在我的InitializeUI()方法不过是一堆 findViewById 和设置 onClickListeners。还要确保调用InitializeUI() in youronCreate()`。

希望这会有所帮助。

于 2013-03-26T15:31:03.727 回答