片段重新定位改变之后每次,无法恢复状态 [英] Fragment recreated every time after orientation change, unable to restore state

查看:154
本文介绍了片段重新定位改变之后每次,无法恢复状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:事实证明,这个问题是来自其他地方。感谢@Luksprog您指出我忽视了。

Update: It turns out that the problem is from elsewhere. Thanks @Luksprog for pointing out what I overlooked.

  1. 在该项目采用Android Studio的抽屉式导航模式创建的。抽屉是在 NavigationDrawerFragment 类实现。
  2. 时,在抽屉里的特定项目被选中的片段持有的观点寻呼机被添加。在code为实现我家的活动。
  3. 当屏幕旋转时,的的onCreate()方法 NavigationDrawerFragment 被调用时,preserving最后选定的项目
  4. 在这里是哪里出了问题 - 在娱乐, NavigationDrawerFragment 将调用选择信息()再次,这将触发我的菜单项目中选择处理程序。这使得搭载Android恢复ListFragment。
  1. The project is created using Android Studio's navigation drawer pattern. The drawer is implemented in the NavigationDrawerFragment class.
  2. The fragment holding the view pager is added when a particular item in the drawer is selected. The code is implemented my home activity.
  3. When screen rotates, the onCreate() method of NavigationDrawerFragment is called, preserving last selected item.
  4. And here is what went wrong - upon recreation, NavigationDrawerFragment will call selectItem() again, which triggers my menu item selected handler. This causes the ListFragment restored by Android.

这可以通过检查在我的菜单中选择处理程序code中的活动菜单项pvented $ P $。

This can be prevented by checking the active menu item in my menu selection handler code.

我要保留的 ViewPager 时,该活动是由什么原因重建,如最后观看网页索引方向的改变。

I want to retain the last viewing page index of the ViewPager when the activity is recreated by whatever reason, e.g. orientation change.

ViewPager 是一个片段(名为 ListFragment ),其附连到的活性。我现在用的是compat的图书馆,所以片段的子类 android.support.v4.app.Fragment

The ViewPager is in a Fragment (named ListFragment), which is attached to an activity. I am using the compat library, so the fragment is a subclass of android.support.v4.app.Fragment.

我认为这可以通过覆盖的onSaveInstanceState()方法,并添加适当的逻辑的onCreate(),因为在文件档案的 DOC

I thought that it could be done by overriding the onSaveInstanceState() method and add appropriate logic in onCreate(), as metioned in the doc:

要正确处理重新启动,但重要的是你的活动   通过正常的活动周期恢复其previous状态,   它的Andr​​oid电话的onSaveInstanceState(),它破坏之前,你的   活动让你可以将数据保存有关应用程序的状态。您   随后的onCreate中恢复状态()或   onRestoreInstanceState()。

To properly handle a restart, it is important that your activity restores its previous state through the normal Activity lifecycle, in which Android calls onSaveInstanceState() before it destroys your activity so that you can save data about the application state. You can then restore the state during onCreate() or onRestoreInstanceState().

不过,情况似乎片段不同。该页面索引可以正确恢复时,我从这个 ListFragment 导航到pssed后退另一个活动和$ P $。然而,当我转动我的设备,页面索引丢失。

But the situation seems different for fragments. The page index can be correctly restored when I navigate from this ListFragment to another activity and pressed "back". However when I rotate my device, the page index is lost.

我添加了一些日志,看看有什么不对。从日志中我发现,虽然的onSaveInstanceState() ListFragment (我称之为ListFragment A)被称为正确,这个特定的片段类不再在活动所示。当方向改变,活性重建,Android把的onSaveInstanceState()然后按 onDetach()分离该片段。然后点击 Android的创建 ListFragment 的新实例(我称之为ListFragment B),并将其安装到新的,旋转的活动。这ListFragment B有一个空的 savedInstanceState 传递给构造函数,从而最后一页指数(和片段A的savedInstanceState任何配置)都将丢失。

I added some logging to see what's wrong. From the log I found that although onSaveInstanceState() of the ListFragment(I'll call it ListFragment A) is called properly, this particular Fragment class is no longer shown in the activity. When the orientation changed and the activity is recreated, Android calls onSaveInstanceState() followed by onDetach() to detach this fragment. Then Android creates a new instance of ListFragment (I'll call it ListFragment B) and attach it to the new, rotated activity. This ListFragment B has an empty savedInstanceState passed to the constructor, and thus the last page index (and any configuration in savedInstanceState of Fragment A) is lost.

其实, ListFragment 的新实例将创建的每个屏幕旋转时的时间,但似乎旧的不会被破坏。我看到类似下面的日志时我旋转设备:

In fact, a new instance of ListFragment will be created every time a screen rotate occurs, but it seems that the old ones will not be destroyed. I see logs like below when I rotate the device:

D/ListFragment﹕ [1110257048] onSaveInstanceState() called, storing last page index 3
D/ListFragment﹕ [1109835992] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108826176] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108083096] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1106541040] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108316656] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1109134136] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108630992] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1108592888] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1109729064] onSaveInstanceState() called, storing last page index 0
D/ListFragment﹕ [1110257048] onDestroy()
D/ListFragment﹕ [1110257048] onDetach()
D/ListFragment﹕ [1109835992] onDestroy()
D/ListFragment﹕ [1109835992] onDetach()
D/ListFragment﹕ [1108826176] onDestroy()
D/ListFragment﹕ [1108826176] onDetach()
D/ListFragment﹕ [1108083096] onDestroy()
D/ListFragment﹕ [1108083096] onDetach()
D/ListFragment﹕ [1106541040] onDestroy()
D/ListFragment﹕ [1106541040] onDetach()
D/ListFragment﹕ [1108316656] onDestroy()
D/ListFragment﹕ [1108316656] onDetach()
D/ListFragment﹕ [1109134136] onDestroy()
D/ListFragment﹕ [1109134136] onDetach()
D/ListFragment﹕ [1108630992] onDestroy()
D/ListFragment﹕ [1108630992] onDetach()
D/ListFragment﹕ [1108592888] onDestroy()
D/ListFragment﹕ [1108592888] onDetach()
D/ListFragment﹕ [1109729064] onDestroy()
D/ListFragment﹕ [1109729064] onDetach()
D/ListFragment﹕ [1110903656] onAttach()
D/ListFragment﹕ [1110903656] onCreate()
D/ListFragment﹕ [1110903656] savedInstanceState is not NULL.
D/ListFragment﹕ [1110903656] Retrieving last page index 3
D/ListFragment﹕ [1110905248] onAttach()
D/ListFragment﹕ [1110905248] onCreate()
D/ListFragment﹕ [1110905248]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110905248]   Retrieving last page index 0
D/ListFragment﹕ [1110906440] onAttach()
D/ListFragment﹕ [1110906440] onCreate()
D/ListFragment﹕ [1110906440]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110906440]   Retrieving last page index 0
D/ListFragment﹕ [1110907632] onAttach()
D/ListFragment﹕ [1110907632] onCreate()
D/ListFragment﹕ [1110907632]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110907632]   Retrieving last page index 0
D/ListFragment﹕ [1110908824] onAttach()
D/ListFragment﹕ [1110908824] onCreate()
D/ListFragment﹕ [1110908824]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110908824]   Retrieving last page index 0
D/ListFragment﹕ [1110910016] onAttach()
D/ListFragment﹕ [1110910016] onCreate()
D/ListFragment﹕ [1110910016]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110910016]   Retrieving last page index 0
D/ListFragment﹕ [1110911208] onAttach()
D/ListFragment﹕ [1110911208] onCreate()
D/ListFragment﹕ [1110911208]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110911208]   Retrieving last page index 0
D/ListFragment﹕ [1110912400] onAttach()
D/ListFragment﹕ [1110912400] onCreate()
D/ListFragment﹕ [1110912400]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110912400]   Retrieving last page index 0
D/ListFragment﹕ [1110913592] onAttach()
D/ListFragment﹕ [1110913592] onCreate()
D/ListFragment﹕ [1110913592]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110913592]   Retrieving last page index 0
D/ListFragment﹕ [1110914784] onAttach()
D/ListFragment﹕ [1110914784] onCreate()
D/ListFragment﹕ [1110914784]   savedInstanceState is not NULL.
D/ListFragment﹕ [1110914784]   Retrieving last page index 0
D/HomeActivity﹕ fragment updated
D/ListFragment﹕ [1110914784] onCreateView()
D/ListFragment﹕ [1111031048] onAttach()
D/HomeActivity﹕ Fragment attached.
D/ListFragment﹕ [1111031048] onCreate()
D/ListFragment﹕ [1111031048]   savedInstanceState is NULL.
D/ListFragment﹕ [1111031048] onCreateView()
D/ListFragment﹕ [1111031048] onResume(), restoring page index 0

这是我后旋转屏幕约10倍的记录。在标签的数字是类'散code()。以上线路显示,的onSaveInstanceState()的onCreate()的previously创建片段,即使仍然可以称为它们由最新的(1111031048)一种取代。

This is the log after I rotated the screen for about 10 times. The number in the tag is the classes' hashCode(). Above lines shows that onSaveInstanceState() and onCreate() of the previously created fragments still get called even after they are replaced by the latest (1111031048) one.

请注意,我的没有的通话 setRetainInstance()在片段类。其实,我都尝试 setRetainInstance(假) setRetainInstance(真),但它不会改变任何东西。

Note that I didn't call setRetainInstance() in the fragment class. In fact, I tried both setRetainInstance(false) and setRetainInstance(true) but it doesn't change anything.

难道我做错什么吗?我可以理解, ListFragment 需要重新创建,但为什么 savedInstanceState 为空?如果这是预期的行为,什么是解决我的需要以正确的方式,即保持网页索引时的配置变化?

Did I do anything wrong here? I can understand that ListFragment needs to be recreated, but why savedInstanceState is null? And if this is the expected behavior, what is the correct way to solve my need, i.e. keeping the page index when configuration changes?

这应该有可能使页面索引类的静态变量,但我不知道这是否是真正解决问题,或只是隐藏它(因为我闻到内存泄漏在日志中以上)。

It should be possible to make the page index a static class variable, but I'm not sure if it is actually solving the issue, or just hiding it (because I smell memory leak in the log above).

推荐答案

由于更新的问题,这又是解决,感谢@Luksprog您指出我忽视了。

As updated in the question, this is resolved and thanks again to @Luksprog for pointing out what I overlooked.

片段的行为实际上对准活动类。

The behavior of Fragment actually aligns with Activity classes.

下面是我的问题的原因:

Here is the cause of my issue:

  • 在该项目利用机器人工作室的创建项目向导提供抽屉式导航模式创建的。抽屉是在 NavigationDrawerFragment 类来实现。
  • 时,在抽屉里的特定项目被选中的片段持有的观点寻呼机被添加。在code为实现我家的活动。
  • 当屏幕旋转时,的的onCreate()方法 NavigationDrawerFragment 被调用时,preserving最后选定的项目
  • 在这里是哪里出了问题 - 在娱乐, NavigationDrawerFragment 将调用选择信息()再次,这将触发我菜单项目中选择处理程序。这将导致 ListFragment 所取代。
  • The project is created using navigation drawer pattern provided by Android Studio's "create project" wizard. The drawer is implemented in the NavigationDrawerFragment class.
  • The fragment holding the view pager is added when a particular item in the drawer is selected. The code is implemented my home activity.
  • When screen rotates, the onCreate() method of NavigationDrawerFragment is called, preserving last selected item.
  • And here is what went wrong - upon recreation, NavigationDrawerFragment will call selectItem() again, which triggers my menu item selected handler. This causes the ListFragment be replaced.

这可以通过检查在我的菜单中选择处理程序code中的活动菜单项pvented $ P $,或通过禁用选择信息()通话。

This can be prevented by checking the active menu item in my menu selection handler code, or by disabling that selectItem() call.

这篇关于片段重新定位改变之后每次,无法恢复状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆