android 多个导航栈,使用片段为Android中的每个选项卡分离回堆栈

我们必须实现与您最近描述的应用程序完全相同的行为。应用程序的屏幕和整体流程已经定义好了,所以我们必须坚持使用它(这是一个iOS应用程序的克隆.)。幸运的是,我们成功地摆脱了屏幕上的后退按钮:)

我们使用TabActivity、FragmentActivity(对片段使用支持库)和片段的混合方式攻击解决方案。在回顾中,我很确定这不是最好的架构决策,但我们成功地让它发挥作用。如果我不得不再做一次,我可能会尝试做一个更基于活动的解决方案(没有片段),或者尝试并且只有一个选项卡的活动,让所有剩下的都是视图(我发现它比整个活动更可重用)。

因此,要求在每个选项卡中都有一些选项卡和可嵌套的屏幕:tab 1

screen 1 -> screen 2 -> screen 3

tab 2

screen 4

tab 3

screen 5 -> 6

等等.。

例如:用户在选项卡1中启动,从屏幕1导航到屏幕2,然后导航到屏幕3,然后切换到选项卡3,从屏幕4导航到6;如果切换回选项卡1,他应该再次看到屏幕3,如果他按回屏幕,他应该返回到屏幕2;再次回到屏幕1;切换到选项卡3,他又在屏幕6。

应用程序中的主要活动是MainTabActivity,它扩展了TabActivity。每个选项卡都与一个活动相关联,比如ActivityInTab1、2和3。然后每个屏幕都是一个片段:MainTabActivity

ActivityInTab1

Fragment1 -> Fragment2 -> Fragment3

ActivityInTab2

Fragment4

ActivityInTab3

Fragment5 -> Fragment6

每个ActivityInTab一次只保存一个片段,并且知道如何将一个片段替换为另一个片段(与ActvityGroup几乎相同)。最酷的是,通过这种方式可以很容易地将每个标签的背板分开。

每个ActivityInTab的功能是完全相同的:知道如何从一个片段导航到另一个片段并维护一个后台堆栈,因此我们将其放入一个基类中。让我们简单地称之为ActivityInTab:abstract class ActivityInTab extends FragmentActivity { // FragmentActivity is just Activity for the support library.

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_in_tab);

}

/**

* Navigates to a new fragment, which is added in the fragment container

* view.

*

* @param newFragment

*/

protected void navigateTo(Fragment newFragment) {

FragmentManager manager = getSupportFragmentManager();

FragmentTransaction ft = manager.beginTransaction();

ft.replace(R.id.content, newFragment);

// Add this transaction to the back stack, so when the user presses back,

// it rollbacks.

ft.addToBackStack(null);

ft.commit();

}}

Active_in_tab.xml就是这样的:<?xml  version="1.0" encoding="utf-8"?>

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/content"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:isScrollContainer="true">

如您所见,每个选项卡的视图布局是相同的。这是因为它只是一个名为内容的FrameLayout,可以保存每个片段。这些片段是有每个屏幕视图的片段。

仅为了增加积分,我们还添加了一些小代码,以便在用户按回并且没有更多的片段可返回时显示一个确认对话框:// In ActivityInTab.java...@Overridepublic void onBackPressed() {

FragmentManager manager = getSupportFragmentManager();

if (manager.getBackStackEntryCount() > 0) {

// If there are back-stack entries, leave the FragmentActivity

// implementation take care of them.

super.onBackPressed();

} else {

// Otherwise, ask user if he wants to leave :)

showExitDialog();

}}

基本上就是这样的安排。正如您所看到的,每个FragmentActivity(或者仅仅是Android>3中的简单活动)都使用它自己的FragmentManager来处理所有的后台堆叠。

像ActivityInTable 1这样的活动非常简单,它只显示它的第一个片段(即屏幕):public class ActivityInTab1 extends ActivityInTab {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

navigateTo(new Fragment1());

}}

然后,如果一个碎片需要导航到另一个片段,它必须做一些讨厌的铸造.但也没那么糟// In Fragment1.java for example...// Need to navigate to Fragment2.((ActivityIntab) getActivity()).navigateTo(new Fragment2());

差不多就是这样了。我很确定这不是一个非常规范的解决方案(而且大多数情况下肯定不是很好),所以我想问经验丰富的Android开发人员如何更好地实现这一功能,如果这不是Android中的“它是如何做到的”,我将非常感谢您能向我介绍一些链接或材料来解释哪些是这个Android解决这个问题的方法(选项卡、选项卡中的嵌套屏幕等等)。请随意在评论中撕开这个答案:)

这个解决方案不太好的一个标志是,最近我不得不在应用程序中添加一些导航功能。一些奇怪的按钮应该将用户从一个选项卡带到另一个选项卡中,然后进入嵌套的屏幕。用编程的方式做这件事很痛苦,因为谁知道谁有问题,以及处理片段和活动何时实际实例化和初始化。我认为如果那些屏幕和标签都只是视图,那就容易多了。

最后,如果您需要生存的方向变化,重要的是,您的片段是创建使用setArguments/getArguments。如果在片段的构造函数中设置实例变量,就会失败。但幸运的是,这真的很容易修复:只需将所有内容保存在构造函数中的setArguments中,然后用onCreate中的getArguments检索这些东西来使用它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值