19

我有两个活动 A 和 B。A 有一个使用 LoaderManager 的 ListFragment,而 B 活动显示有关在 A 的 ListFragment 中选择的项目的详细信息。我刚刚注意到,当我使用后退按钮从 B 回到 A 时,ListFragment 中的位置会保留,但是当我使用操作栏中的向上按钮(左点插入符号)时,A 活动被重新创建,因此列表视图中的位置丢失。

我想解决这个问题,但我不确定如何正确解决这个问题。

我想出了这个解决方案:

a) 使用onBackPressed()

android.R.id.home替换B活动中(向上操作栏按钮)的默认实现,而不是NavUtils.navigateUpFromSameTask(this)调用onBackPressed()活动方法的函数。我已经对其进行了测试,并且可以正常工作。

b) 继续使用NavUtils.navigateUpFromSameTask(this)

但是在 A 活动使用的 ListFragment 方法onSaveInstanceState期间实现并恢复 listView 位置。onCreate(我还没有测试过这种方法)


哪种解决方案更好?或者还有其他(更好的)解决方案吗?

解决方案a)非常简单直接,但b)可能更好,因为使用了 up caret 的默认实现。

欢迎任何想法。谢谢。

4

2 回答 2

10

解决方案c是正确的选项。不过,首先解释一下解决方案a的问题。

在您的活动中拥有两个后退按钮绝对没有意义。此外,选项a实际上打破了向上按钮。向上按钮的目的是为用户提供一种在他们从外部来源登陆您的应用程序时留在您的应用程序中的方式。例如,如果您从外部活动 C 进入活动 B,并且您正在使用选项a,那么在活动 B 中按“向上”将导致显示活动 C。您想要的行为是显示活动 A。

如您所见,解决方案b是在正确的轨道上。您肯定想A 而不是回到C。但是,简单地将状态存储在其中onSaveInstanceState不会导致状态被保留。这是因为onSaveInstanceState只有当您的应用程序可能被系统杀死时才会被调用。如果您的应用程序被手动销毁,则不保证会调用它,并且在创建 Activity 的新实例时肯定不会调用它。如果 Intent 启动一个新活动,那么它的状态将不会从其他活动恢复。

那么,解决方案是您必须将任何持久性内容写入共享首选项文件(或自定义持久性替代文件)。这样做时,您可以保证 Activity 的所有实例在多个任务之间共享相同的状态,只要它们的 onResume(或您恢复状态的任何位置)被调用。或者:

如果您确切地知道您希望导航如何工作,则可以通过使用 Intent 标志和 Activity 任务关联性的组合来避免将所有内容写入持久状态。如果您想使用与 up 相同的活动,即使您从外部来源导航到应用程序,那么您可以将 Activity A 的关联保留为默认值(链接到应用程序)并使用 Intent.FLAG_ACTIVITY_CLEAR_TOP 之类的内容。

就个人而言,我会首先尝试使用 Intent 标志方法,如果失败则回退到持续写入状态。如果可以避免的话,您只是不希望滚动位置位于持久存储上。

于 2013-09-20T00:10:32.750 回答
0

查看此演示文稿:https ://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android 。它回答了你所有的问题。

于 2013-12-12T14:44:22.977 回答