在 Android 中处理活动轮换
我需要为我的活动的纵向和横向应用不同的布局。此外,如果方向是纵向,我需要显示警报。
我已在 AndroidManifest.xml 中指定了 android:configChanges="orientation|keyboardHidden"
我还像这样重写 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 被调用两次?我怎样才能避免它?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
请参阅我对另一个问题的回答: https://stackoverflow.com/a/3252547/338479
简而言之,处理配置正确的改变是很难做到的。最好实现 onRetainNonConfigurationInstance()在您的应用程序由于配置更改而即将停止并重新启动之前调用。使用此方法保存您想要的任何内容(“这是一个不错的选择”),然后让系统拆除您的应用程序。
当您的应用程序使用新配置重新启动时,请使用 getLastNonConfigurationInstance () 检索您刚刚保存的状态,并使用它来继续您的应用程序,而无需对捆绑包和共享首选项进行任何处理。
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.
您可以简单地保存之前的方向并检查它是否确实发生了变化。
如果您在
AndroidManifest.xml
android:configChanges
中将 Activity 的keyboardHidden|orientation
设置为onCreate
等。不会被调用。这使得实施变得更加容易实施。但当然布局也会从纵向变为横向。You can simply save the previous orientation and check if it has really changed.
If you set in
AndroidManifest.xml
android:configChanges
tokeyboardHidden|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.您选择以这种方式处理轮换有什么特殊原因吗?虽然它更快,因为活动不会在方向改变时重新启动,但如果我没记错的话,通常不建议这样做。处理方向更改的另一种方法是重写
onConfigurationChanged()
,而是重写onCreate()
、onStart()
或onResume()
这样,然后指定两种布局 - 一种用于纵向,一种用于横向。布局的纵向版本将保留在
res/layout/whatever.xml
中,横向版本将保留在res/layout-land/whatever.xml
中。 AndroidGuys 就这个主题写了很多好文章,请参阅 http: //androidguys.com/?s=rotational+forces&x=9&y=9Is there any particular reason you chose to handle rotation in this manner? While it is quicker since the activity doesn't get restarted on an orientation change, it isn't typically recommended, if I recall correctly. Another way to handle orientation changes is instead of overriding
onConfigurationChanged()
, overridingonCreate()
,onStart()
oronResume()
such thatand then specifying two layouts - one for portrait, one for landscape. The portrait version of the layout would remain at
res/layout/whatever.xml
, and the landscape version would live inres/layout-land/whatever.xml
. The AndroidGuys had written a bunch of good articles on this topic, see http://androidguys.com/?s=rotational+forces&x=9&y=9我很确定您会想使用 onCreate 而不是 onStart。唯一的区别似乎是当应用程序到达前台时 onStart 将被调用。在这种情况下,您不想让用户等待您重新初始化 UI。否则,只需根据该 if 条件更改 setContentView 调用即可。
I'm pretty sure you would want to use onCreate rather than onStart. The only difference appears to be that onStart will get called when the application comes to the foreground. That wouldn't be a case where you'd want to make the user wait for you to re-initialize the UI. Otherwise, just change your setContentView call based on that if condition.
Android 在更改方向时会启动 Activity 的新实例,因此使用 onCreate 是理想的方法。显然,您必须保存/恢复活动的数据,以便从上次中断的地方继续操作 - 但无论如何您都应该这样做,因为任何数量的事件都可能使您的应用程序失去焦点/终止。
Android starts a new instance of your activity when changing orientation so using onCreate is the ideal method. You will have to save/restore your activity's data obviously in order to pick up where you left off - but you should be doing this anyway since any number of events can unfocus/kill your application.