具有多个父级的Activity的Android向上导航

39
我有一个问题,需要在这个导航树的应用程序上实现向上导航

App navigation tree

后退按钮的标准实现是可以的。

问题出现在尝试实现向上按钮时。

我的期望:

  • 当用户在详情 5 活动上并按下向上按钮时,应用程序转到列表 3 活动
  • 当用户在详情 7 活动上并按下向上按钮时,应用程序返回到主页活动

因此,换句话说,我希望在后退栈上具有此行为:

app backstack clear

Android文档(实现祖先导航)建议使用以下代码来处理向上导航

Intent parentActivityIntent = new Intent(this, MyParentActivity.class);
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();

但是由于不同的导航路径上,详细活动(Detail Activity)的父活动不同,我不知道它到底是哪一个。所以我不能在意图中调用它。

有没有一种方法可以知道Android后台堆栈中真正的父活动?

如果没有,有没有一种方法在这个应用程序中实现正确的向上导航(up navigation)

3个回答

22

我将坚持对Paul答案的评论:

这个想法是拥有一个最近遍历过的活动堆栈。例如:

public static Stack<Class<?>> parents = new Stack<Class<?>>();

现在,对于你所有的父活动(被认为是父活动的活动 - 例如,在你的情况下:List和Home),你需要将以下内容添加到它们的onCreate中:

protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     parents.push(getClass()); 
     //or better yet parents.push(getIntent()); as @jpardogo pointed
     //of course change the other codes to make use of the Intent saved.

     //... rest of your code
}

当你想要返回到Parent活动时,你可以根据你的代码使用以下方法:

Intent parentActivityIntent = new Intent(this, parents.pop());
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();

我希望我是正确的 (:


我已经成功地实现了你的解决方案。它运行良好。谢谢!我不得不将起始意图的额外信息添加到堆栈中,以恢复具有正确意图附加项的父Activity,但这只是一个实现细节。 - ol_v_er
是的,它并不真正“肮脏”,它运行良好且易于单元测试。 - ol_v_er
为什么它不符合Android导航模式?我尝试按照应该的方式精确实现它。我错在哪里了? - ol_v_er
我正在做同样的事情来解决这个问题,但是不是在onCreate中推送(push)getClass(),而是在onPause中推送(push)getIntent()。否则会出现空栈和活动未获得正确附加数据的问题。 - jpardogo
看起来很不错,谢谢你。但是关于savedInstanceState呢?或者一般的配置更改(如屏幕方向更改)呢?在这种情况下,父意图将被多次插入到堆栈中。这可能只是实现问题,但值得考虑并记在心中。 - Speedy
显示剩余2条评论

2
那是一个棘手的问题,我认为这真正展示了应对Android“向上按钮”的用户体验决策的困难。因此,你的问题没有明确的答案。
我有两个可能的解决方案。
1. 模仿返回按钮的行为。
您可以考虑在启动“详情”页面时向意图添加额外信息,以便通知那些活动它们需要在按下“android.R.id.home”时启动哪个活动。
这实际上意味着您的应用程序“返回”到其公共祖先,而不仅仅是重新启动“主页”。
另一种实现方式可能是执行onBackPressed()而不是使用Intent.FLAG_ACTIVITY_CLEAR_TOP启动“主页”,但请记住,相关的动画与正常的“向上”操作不同。
2. 跳过中间活动并回到主页。
一些应用程序将“向上按钮”视为“主页按钮”。您可以考虑始终使用Intent.FLAG_ACTIVITY_CLEAR_TOP重新启动“主页”。

1
我从来没有实现过这个,也从未使用过这个,但应用程序将有多条路径,而且他知道哪些是候选父级。他不能将主页按钮视为包含其“父级”活动的特殊返回堆栈吗?在代码方面:他可以保持一堆启动的父级活动,并在按下主页时弹出此堆栈。(仅供参考) - Sherif elKhatib
@SherifelKhatib 应用程序无法查询后堆栈,因此恐怕这种方法行不通。我认为这并不是什么大问题,因为如果活动知道它是如何启动的,它就可以相应地进行操作。 - Paul Lammertsma
感谢您的回答,我的第一个后向实现并没有像我想的那样正常工作。在Extra中传递父项有点棘手,所以我实现了@Sherif-elKhatib的解决方案。返回主页按钮不是我想要的行为,但这可能是解决问题的有用方式;-) - ol_v_er

0

这篇文章肯定是旧的了,但是当我在学习SharedPreferences时,我认为可以将这些信息堆叠在sharedPreferences数据中,并在下降到2个父级之前每次修改其值。然后通过阅读它,您应该能够直接知道您的父级,而无需为此构建整个类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接