Android导航标签:恢复片段视图状态

Jan*_*ken 12 android-fragments android-tabs

我试图了解在导航选项卡中使用片段时如何保留片段视图状态.在我的努力中,我遇到了两个问题,我找不到任何适当的解决方案.

我有两个标签,Tab1和Tab2.Tab1的布局由定义FragmentA,Tab2的布局由定义FragmentB.我按照这里给出的方法(编辑:文档已经改变,因为这个问题被问到).

第一个问题:即使我的视图有ID,当重新连接片段(在制表符切换旋转之后)时,它们的状态也不会完全恢复.特别是:一个EditText带有ID 确实保存其输入的文字,但它并不能挽救它的启用状态.此外,如果启用或禁用按钮,即使它们具有ID,也不会保存.我发现了这个问题的两种可能的解决方法:

  1. 使用hide()/show()而不是attach()/detach()切换标签时.
  2. in onPause(),将当前片段视图状态保存View在片段via 的实例变量中getView().在onCreateView(Bundle savedInstanceState)检查该字段不为空,如果是这样的情况下,返回此字段的值.这个解决方案看起来很糟糕,我被告知它可能也会在我的应用程序中引入内存泄漏.

第二个问题:考虑以下用户交互:用户在Tab1上启动并进行一些更改,使Tab1的视图状态处于与其默认状态不同的状态(我们希望片段通过制表符和设备倾斜来保存此视图状态) .然后用户转到Tab2.然后用户倾斜她/他的设备(仍然在Tab2).然后用户切换到Tab1(在新的屏幕方向).现在,问题是:当用户最初从Tab1切换到Tab2时,片段被分离,从而丢弃其视图(即使片段实例仍然存在).当用户然后倾斜设备时,活动 - 从而与之相关FragmentA并且FragmentB与之相关联 - 被破坏.由于FragmentA此时不再有视图(记住:它已被分离),我们无法在调用期间保存其视图元素的状态(例如,启用/禁用了哪些按钮)FragmentA.onSaveInstanceState(Bundle savedInstanceState).在这种情况下如何恢复片段视图状态?唯一可行的解​​决方案是将每个视图元素的不同状态标志保存为SharedPreferences吗?对于这样的"日常工作"来说,这似乎太复杂了.

ant*_*nyt 7

问题1:

默认情况下,Android不会保存您的视图启用状态.似乎只保存了直接受用户操作(没有附加代码)影响的事物.对于普通视图,不保存任何信息,对于TextView,其中EditText是子类,则保存输入的文本(如果设置了freezesText).

如果你想要保存任何其他东西,你必须自己做.是一个问题,其中一些答案显示了如何实现自定义视图状态保存.如果你采用这种方法,你可以坚持使用附加/分离.

问题2:

你是对的,你的视图已被销毁后可以调用Fragment.onSaveInstanceState(Bundle).但是,这不是您应该保存视图状态的位置.Android会在分离片段时破坏您的视图之前调用View.onSaveInstanceState().它会保存此状态,并在您再次附加片段时将其返回给您.这正是当您在没有旋转的情况下在标签之间切换时发生的情况.分离时不调用Fragment.onSaveInstanceState(Bundle).即使您旋转设备,由于分离而保存的视图状态也将保持不变.如果按照上面的指示实现View.onSaveInstanceState(),即使在Tab1-Tab2-rotate-Tab1方案中,您的视图状态也将被正确保存和恢复.

附注:当您尝试旋转时,文档中 的示例代码似乎存在一些问题.TabListener的生命周期与Activity的生命周期相同 - 每次旋转时都会创建一个新生命周期.这意味着每次旋转时它也会丢失对片段的内部引用.添加的片段会自动重新创建,因此TabListener不需要在轮换后尝试创建新实例并添加它.相反,对于内部引用,它应该只是尝试在片段管理器中找到具有适当标记的片段.旋转后它仍然存在.

另一个问题是未保存选定的选项卡,但这在示例的底部注明.您可以将其保存在Activity.onSaveInstanceState(Bundle)中.

  • 哇,那太疯狂了.我认为恢复内置视图的视图状态将是一个经常重新出现的任务,以支持它作为标准功能.假设我应该编写一个库供以后使用.谢谢你帮助我.这让我生气了两个星期了,呵呵. (2认同)