5

我需要为我的活动的纵向和横向应用不同的布局。此外,如果方向是纵向,我需要显示警报。

我已经android:configChanges="orientation|keyboardHidden"在 AndroidManifest 中指定了。我还像这样覆盖 onConfigurationChanged 方法:

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    Log.d("tag", "config changed");
    super.onConfigurationChanged(newConfig);

    int orientation = newConfig.orientation;
    if (orientation == Configuration.ORIENTATION_PORTRAIT)
        Log.d("tag", "Portrait");
    else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
        Log.d("tag", "Landscape");
    else
        Log.w("tag", "other: " + orientation);

    ....
}

从横向旋转到纵向日志看起来像:

config changed
Portrait

但是从纵向变为横向时,它看起来像

config changed
Portrait
config changed
Landscape

为什么 onConfigurationChanged 被调用两次?我怎样才能避免它?

4

5 回答 5

3

See my answer to another question here: https://stackoverflow.com/a/3252547/338479

In short, handling configuration changes correctly is hard to do. It's best to implement onRetainNonConfigurationInstance() which is called just before your application is about to be stopped and restarted due to a configuration change. Use this method to save anything you want ('this' is a good choice) and then let the system tear down your app.

When your app gets restarted with the new configuration, use getLastNonConfigurationInstance() to retrieve the state you just saved, and use it to continue your application without all that mucking about with bundles and shared preferences.

于 2013-01-25T16:19:33.560 回答
1

您可以简单地保存以前的方向并检查它是否真的改变了。

If you set in AndroidManifest.xml android:configChanges to keyboardHidden|orientation for your activity, onCreate etc... won't be called. That makes the implementation significantly easier to implement. But of course layout will change from portrait to landscape as well.

于 2012-08-11T23:39:51.240 回答
0

您选择以这种方式处理旋转有什么特别的原因吗?虽然它更快,因为活动不会在方向更改时重新启动,但如果我没记错的话,通常不建议这样做。处理方向更改的另一种方法是替代覆盖、onConfigurationChanged()覆盖onCreate()或这样onStart()onResume()

@Override
public void onStart() {
    super.onStart();
    int orientation = getWindowManager().getDefaultDisplay().getOrientation();
    if(orientation == Configuration.ORIENTATION_PORTRAIT) {
        Log.i(TAG, "Orientation is portrait");
        // show whatever alerts here
    }
}

然后指定两种布局 - 一种用于纵向,一种用于横向。布局的纵向版本将保留在res/layout/whatever.xml,而横向版本将继续存在res/layout-land/whatever.xml。AndroidGuys 写了很多关于这个主题的好文章,见http://androidguys.com/?s=rotational+forces&x=9&y=9

于 2010-09-25T19:32:24.790 回答
0

我很确定您会想要使用 onCreate 而不是 onStart。唯一的区别似乎是当应用程序进入前台时会调用 onStart。这不是您想让用户等待您重新初始化 UI 的情况。否则,只需根据该 if 条件更改您的 setContentView 调用。

于 2010-09-25T21:37:16.083 回答
0

Android 在改变方向时会启动一个新的 Activity 实例,因此使用 onCreate 是理想的方法。显然,您必须保存/恢复您的活动数据才能从中断的地方继续 - 但无论如何您都应该这样做,因为任何数量的事件都可能使您的应用程序失去焦点/杀死您的应用程序。

于 2010-09-26T17:49:05.997 回答