Android方向更改调用onCreate

时间:2010-06-22 23:31:20

标签: android android-activity android-orientation

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

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

我到目前为止唯一的解决方案是调用finish()然后调用startActivity()来基本上重新启动活动并使用新结果。我确信必须有一个更简单的解决方案,而且我做了一些非常无趣的事情。

有更好的方法吗?

3 个答案:

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