我创建了一个搜索屏幕,其中包含一个用于关键字,过滤器和搜索按钮的标签,以及三个针对不同类型结果的可选标签(每个标签包含ListView
和ArrayAdapter
)。启动活动时,如果已执行搜索,开发人员可以选择将结果作为额外Parcelable[]
传递。在onCreate()
方法中,我正在为Parcelable[]
传递的三个标签中的每一个创建。
当我从过滤器选项卡上的按钮调用搜索时,我清除选项卡并使用新结果重新创建它们,这非常有效。问题是,当您旋转设备时,Android的自动方向切换支持似乎会重新创建整个活动,并调用onCreate()
。这意味着我的搜索结果会重置为启动活动时传递的Parcelable[]
。
我到目前为止唯一的解决方案是调用finish()
然后调用startActivity()
来基本上重新启动活动并使用新结果。我确信必须有一个更简单的解决方案,而且我做了一些非常无趣的事情。
有更好的方法吗?
答案 0 :(得分:31)
有资源。只需将configChanges属性添加到AndroidManifest.xml,就像:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden" />
Activity restart on rotation Android How do I disable orientation change on Android? http://developer.android.com/guide/topics/manifest/activity-element.html#config
答案 1 :(得分:14)
您所描述的是默认行为。您必须通过添加以下内容来自行检测和处理这些事件:
android:configChanges
到您的清单,然后是您要处理的更改。因此,对于方向,您将使用:
android:configChanges="orientation"
要打开或关闭键盘,您可以使用:
android:configChanges="keyboardHidden"
如果你想同时处理它们,你可以用管道命令分开它们,如:
android:configChanges="keyboardHidden|orientation"
这将在您调用的onConfigurationChanged
中触发Activity
方法。
如果覆盖该方法,则可以传入新值。
希望这有帮助。
答案 2 :(得分:1)
一个选项是使用android:configChanges="orientation"
告诉android您要自己处理配置更改,而不是让它重新创建Activity。但是,不建议这样做:
在运行时发生配置更改时,活动被关闭 关闭并默认情况下重新启动,但是使用此声明配置 属性将阻止活动重新启动。相反, 活动仍在运行,其onConfigurationChanged()方法为 叫。注意:应避免使用此属性,并且只能将其用作 不得已。请阅读处理运行时更改以获取更多信息 有关如何正确处理由于以下原因引起的重启的信息 配置更改。 (Source)
有另一种方法可以在配置更改期间保留对象:ViewModel可用于为数据定义包装类。每个Activity实例似乎都有自己的一组ViewModel,可以通过
进行访问MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
,并且如果在其中使用LiveData
,则可以订阅文档中概述的数据更改。这是他们的示例,以防万一链接消失:
建筑组件为UI提供ViewModel帮助器类 负责为UI准备数据的控制器。 ViewModel对象在配置期间会自动保留 进行更改,以便它们保存的数据可立即用于下一个 活动或片段实例。例如,如果您需要显示一个 您的应用中的用户列表,请确保将职责分配给 获取并保留ViewModel的用户列表,而不是 活动或片段,如以下示例代码所示:
public class MyViewModel extends ViewModel { private MutableLiveData<List<User>> users; public LiveData<List<User>> getUsers() { if (users == null) { users = new MutableLiveData<List<User>>(); loadUsers(); } return users; } private void loadUsers() { // Do an asynchronous operation to fetch users. } } You can then access the list from an activity as follows: public class MyActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { // Create a ViewModel the first time the system calls an activity's onCreate() method. // Re-created activities receive the same MyViewModel instance created by the first activity. MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); model.getUsers().observe(this, users -> { // update UI }); } }
如果重新创建活动,它将收到相同的MyViewModel 第一个活动创建的实例。当。。。的时候 所有者活动完成后,框架将调用ViewModel 对象的onCleared()方法,以便清理资源。