当屏幕方向改变时,不要重新加载应用程序。

164

当屏幕旋转时,我希望什么也不改变。我的应用程序在首次加载时显示随机图像,旋转设备不应选择另一个随机图像。简单地说,我该如何停止这种行为?


1
也可以通过代码锁定(并可能解锁)屏幕方向。只需从 https://github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/delight/android/baselib/Screen.java 调用 Screen.lockOrientation(this) 即可。它允许解锁清单无法完成的操作。 - caw
@Escobar Ceaser 这个问题的适当解决方案是什么?我也有同样的需求。 - Prabs
我想在代码中以编程方式实现这个。 - pollaris
17个回答

274

通常有三种方法可以实现此功能:

  1. 如一些答案所建议的那样,您可以区分活动是第一次创建还是从savedInstanceState中恢复。这可以通过覆盖onSaveInstanceState并检查onCreate的参数来完成。

  2. 您可以通过在清单文件中的<activity>标签中添加android:screenOrientation="portrait"(或"landscape")来锁定活动在一个方向上。

  3. 您可以通过在<activity>标签中指定android:configChanges="orientation|screenSize"来告诉系统您要自行处理屏幕更改。这样,活动将不会重新创建,而是会收到回调(您可以忽略它,因为它对您没有用)。

个人而言,我会选择(3)。当然,如果将应用程序锁定在一个方向上对您来说没问题,您也可以选择(2)。


13
所以你是在问对于第三个问题,你的意思是只要在清单文件中添加那一行就可以了吗?因为这样做并没有起作用。 - Jimmy D
2
#3 请查看 https://dev59.com/inRB5IYBdhLWcg3w9Lzn - Yeo
17
对于 Android 3.2 及以上版本,您需要添加 android:configChanges="orientation|screenSize" 属性,以避免屏幕旋转时发生重启。 - Pacerier
10
“android:configChanges="orientation|screenSize" 对我有用。感谢 @Pacerier。” - Don Larynx
1
请在API >=13的情况下,使用android:configChanges="orientation|screenSize"值更新您的第三个答案,因为很多人将您的答案视为主要答案! - radistao
显示剩余11条评论

219
Xion的回答接近正确,但是#3(android:configChanes="orientation") 只有在应用程序API级别为12或更低时才起作用。 在API级别13或以上,当方向改变时屏幕大小也会改变,因此这仍然会导致活动在方向改变时被销毁并重新启动。 只需像下面一样添加"screenSize"属性即可:
<activity
    android:name=".YourActivityName"
    android:configChanges="orientation|screenSize">
</activity>

现在,当您更改方向时(并且屏幕大小发生变化),活动保持其状态,并调用onConfigurationChanged()方法。这将在方向更改时保留屏幕上的任何内容(例如 Webview 中的网页)。

从此网站中了解到这一点:http://developer.android.com/guide/topics/manifest/activity-element.html

但是,这显然是一种不好的实践方式,请阅读下面有关处理运行时更改的链接:

http://developer.android.com/guide/topics/resources/runtime-changes.html


2
谢谢...在"orientation"后添加"screenSize"后它可以工作。 - Pratik Butani
适用于三星Galaxy Nexus安卓4.2.1!android:configChanges="orientation|screenSize" - Vincent Ducastel
7
不良的做法?噗,现实生活中人们有期限,只要有效就行了 ;) - Kacy
1
如果这是一种不好的做法,那么为什么会得到这么多赞? - Sharp Edge
@SharpEdge 因为人们懒惰。 - Marc Plano-Lesay
显示剩余7条评论

27

你只需要打开 AndroidManifest.xml 文件,在你的活动标签中输入以下代码,就像上面有人提到的那样:

您只需要前往 AndroidManifest.xml 文件,并在您的活动标签内或内部键入此行代码,正如上面有人所说:

(Two possible translations based on the target audience)
android:configChanges="orientation|screenSize"

那么,你会得到像这样的东西:

<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>

希望它能够正常工作!


它没有加载我的layout-land布局。:( 对我没有用。 - piyush poriya

16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>
在清单文件的活动选项卡中添加android:configChanges="orientation|screenSize"即可。这样,当设备方向更改时,Activity就不会重新启动了。

它正在工作。但是当我为每个方向使用单独的布局layout.xml和layout-land.xml时,它会将横向布局应用于两个方向。如果我只使用“orientation”,它会给出我期望的结果,但需要重新加载。你能帮忙解决吗? - Karthikeyan Ve
1
@KarthikeyanVe 当你试图作弊时,这就是问题所在。你必须重新启动你的活动来改变布局。直接使用真正的解决方案,即使用 onSaveInstanceState()onCreate() - Marc Plano-Lesay
@MarcPlano-Lesay,我该怎么做? - Ahsan
@Weaboo 实际解决方案已经在问题中链接:https://developer.android.com/guide/topics/resources/runtime-changes.html - Marc Plano-Lesay
@MarcPlano-Lesay 我为纵向和横向模式分别设置了布局,如果我在横向或纵向模式下打开我的应用程序,它可以正常工作,但是每当我尝试在运行时更改方向时,它就会关闭我的应用程序。然而,当我登录到我的应用程序,然后导航到MainActivity并尝试更改方向时,它会重新加载该活动并正常工作。现在的问题是为什么?我的代码中是否存在逻辑错误?我不知道,但我已经尝试过多次调试应用程序,但是我找不到任何问题。此外,我不想重新启动我的活动,为什么我们不能只是在配置更改时自适应相应的布局呢? - Ahsan

11

我的经验告诉我,与其试图强行灌输非默认行为,不如妥善处理方向变化问题更佳。

onSaveInstanceState()中保存当前显示的图像,并在应用程序再次运行时通过onCreate()正确地恢复它。


#3是完全有效的解决方案。它是解决这个确切问题的确切工具。为什么你说它是硬塞的? - Pacerier
1
@Pacerier 只需阅读文档。“注意:应避免使用android:configChanges,仅在最后一步使用。有关如何正确处理由配置更改引起的重启的更多信息,请阅读处理运行时更改。” - Marc Plano-Lesay
你能够提供一个保存和恢复的例子吗? - pollaris

6

这个解决方案是目前为止最好的。在您的清单文件中添加以下内容:

<activity
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:name="your activity name"
    android:label="@string/app_name" 
    android:screenOrientation="landscape">
  </activity
在你的活动类中添加以下代码:
@Override
public void onConfigurationChanged(Configuration newConfig) 
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //your code
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
  //your code

    }
}

6

在清单文件中为每个活动添加此内容。这将有所帮助。

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"

screenLayout 对我有效,防止在 Android 分屏应用时调整大小时进行刷新。 - Terren

4
在清单文件中的所有应用程序活动标签上添加android:configChanges="keyboardHidden|orientation|screenSize"

3
只需将此添加到您的AndroidManifest.xml中。
<activity android:screenOrientation="landscape">

我的意思是,有一个活动标签,请将其添加为另一个参数。如果需要纵向方向,请将横向更改为纵向。希望这能帮到你。


我并不想取消屏幕旋转的功能,我只是不希望我的应用程序重新加载...就像我之前提到的那样。 - Jimmy D
PS...这样做也没有用。它只是强制应用程序以特定方向显示。旋转屏幕仍会重新加载活动。 - Jimmy D

2
如Pacerier所提到的, android:configChanges="orientation|screenSize" 这段代码与Android设备屏幕方向和大小有关。

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