15

我制作了一个搜索屏幕,其中有一个用于关键字、过滤器和一个搜索按钮的选项卡,以及三个用于不同类型结果的可选选项卡(每个选项卡都包含一个ListView和一个ArrayAdapter)。Parcelable[]启动活动时,如果已经执行了搜索,开发人员可以选择将结果作为额外的传递。在该onCreate()方法中,我正在为Parcelable[]传递的三个选项卡中的每一个创建。

当我从过滤选项卡上的按钮调用搜索时,我会清除选项卡并使用新结果重新创建它们,效果很好。问题在于,当您旋转设备时,Android 的自动方向切换支持似乎会重新创建整个活动,调用onCreate(). 这意味着我的搜索结果Parcelable[]在启动活动时被重置为传递。

到目前为止,我唯一的解决方案是调用finish()thenstartActivity()以使用新结果重新启动活动。我确信一定有一个更简单的解决方案,而且我做了一些非常愚蠢的事情。

有一个更好的方法吗?

4

3 回答 3

33

当然有。只需将 configChanges 属性添加到您的 AndroidManifest.xml,如下所示:

<activity android:name=".MyActivity" 
          android:configChanges="orientation|keyboardHidden" /> 

Android 上的旋转活动重启 如何禁用 Android 上的方向更改? http://developer.android.com/guide/topics/manifest/activity-element.html#config

于 2010-06-22T23:55:48.290 回答
15

您描述的是默认行为。您必须自己检测和处理这些事件,方法是添加:

android:configChanges

到您的清单,然后是您要处理的更改。因此,对于方向,您将使用:

android:configChanges="orientation"

对于打开或关闭的键盘,您将使用:

android:configChanges="keyboardHidden"

如果你想同时处理这两种情况,你可以使用管道命令将它们分开,例如:

android:configChanges="keyboardHidden|orientation"

这将触发您调用onConfigurationChanged的任何方法。Activity如果您覆盖该方法,您可以传入新值。

希望这可以帮助。

于 2013-03-15T13:05:18.427 回答
1

一种选择是android:configChanges="orientation"告诉 android 你想自己处理配置更改,而不是让它重新创建 Activity。但是,不鼓励这样做:

当运行时发生配置更改时,默认情况下会关闭并重新启动 Activity,但使用该属性声明配置会阻止 Activity 重新启动。相反,活动保持运行并调用其 onConfigurationChanged() 方法。注意:应避免使用此属性,仅将其用作最后的手段。有关如何正确处理由于配置更改而重新启动的更多信息,请阅读处理运行时更改。(来源

在配置更改期间保留对象有另一种方式:ViewModel可用于为您的数据定义包装类。Activity 的每个实例似乎都有自己的一组 ViewModel,可通过

MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);

如果您LiveData在其中使用,您可以订阅文档中概述的数据更改。这是他们的示例,以防万一链接在某个时候失效:

架构组件为负责为 UI 准备数据的 UI 控制器提供 ViewModel 帮助器类。ViewModel 对象在配置更改期间自动保留,以便它们保存的数据可立即用于下一个活动或片段实例。例如,如果您需要在应用程序中显示用户列表,请确保将获取和保留用户列表的责任分配给 ViewModel,而不是 Activity 或 Fragment,如以下示例代码所示:

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() 方法,以便它可以清理资源。

于 2019-01-02T17:02:01.257 回答