【问题标题】:Removing and adding activities to the back stack删除和添加活动到后台堆栈
【发布时间】:2013-11-27 11:43:48
【问题描述】:

Navigation Drawer 的“交叉导航到较低层次结构后的系统返回”部分中,他们说:

如果用户从导航导航到较低层次的屏幕 抽屉和屏幕有一个直接的父级,那么返回堆栈是 reset 和 Back 指向目标屏幕的父级。这回 行为与用户从 通知。

我知道可以通过使用 FLAG_ACTIVITY_CLEAR_TOP 和 FLAG_ACTIVITY_NEW_TASK 启动活动来重置后退堆栈,但这在这里似乎不可用,因为它不会为较低的 1.1.1 创建后退堆栈。

知道如何在启动 Lower 1.1.1 时从堆栈中删除 TopView2 并同时添加 TopView1 -> Lower 1.1 back stack 吗?考虑到导航抽屉文档中提到了这一点,我期待一个简单的解决方案。

【问题讨论】:

  • 我的回答有用吗?您是否尝试过实现向上导航?有什么结果或新问题吗?
  • 似乎很有用 - 我知道除了意图标志之外还有其他东西可以使用。我还没有尝试实现它,我们很快就会切换到它。答案非常长,带有摘要的第一句话会很有用。谢谢!

标签: android navigation-drawer


【解决方案1】:

编辑合成版:

1) 在清单文件中声明应用的层次导航结构。

2)您应用的根 Activity 应该在您的应用层次结构中的 TopViews 之间执行视图切换。*

3) 层次结构中较低的活动应执行“选择性向上”导航。

*重要提示:当事务用于水平导航时,例如切换选项卡或导航抽屉顶视图时,不应将事务添加到后台堆栈。


完整说明:

您应该避免在导航抽屉等新导航模式中使用 Intent Flags,原因如下:

  • 意图标志并不是真正的 API。
  • 某些标志只能在精确组合中使用。
  • 许多标志与大多数第 3 方应用程序无关。
  • 与活动 launchMode 重叠/冲突。
  • 令人困惑的文档。
  • 实施可能是一个反复试验的过程。

改为选择新的 Navigation API:

  • Jelly Bean 及更高版本的原生向上导航。
  • 基于为清单中的每个 <activity> 指定的分层元数据。
  • 支持库通过NavUtils 为早期的 android 版本提供等效功能。
  • TaskStackBuilder 为跨任务导航提供了额外的实用程序。

所以要回答你的问题,大致思路是:

1)您需要在清单文件中声明每个活动的逻辑父级,使用android:parentActivityName 属性(和相应的<meta-data> 元素),例如:

<application ... >
    ...
    <!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.myapp.RootDrawerActivity" ...>
        ...
    </activity>
    <!-- A child of the root activity -->
    <activity
        android:name="com.example.myapp.Lower11 "
        android:label="@string/lower11"
        android:parentActivityName="com.example.myapp.RootDrawerActivity" >
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myapp.RootDrawerActivity" />
    </activity>
    <activity
        android:name="com.example.myapp.Lower111 "
        android:label="@string/lower111"
        android:parentActivityName="com.example.myapp.Lower11" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myapp.Lower11" />
    </activity>
</application>

2) 在您的根 Activity 中,抽屉项目选择应通过替换 Activity 的当前片段内容来启动“视图切换”操作。

视图切换遵循与列表或标签导航相同的基本策略,因为视图切换不会创建导航历史记录。 此模式应仅在任务的根活动中使用,为导航层次结构更下方的活动(在您的情况下为下 1.1 和下 1.1.1)保留某种形式的向上导航活动。这里重要的是,您不需要从堆栈中删除 TopView2,而是在将视图(或片段 ID)的位置作为额外传递之前执行注释的视图切换。

在您的根 Activity 中执行以下操作:

@Override
protected void onDrawerItemSelected(int position) {

        // Update the main content by replacing fragments
        CategoryFragment fragment = new CategoryFragment();
        Bundle args = new Bundle();
        args.putInt(RootDrawerActivity.ARG_SORT, position);
        fragment.setArguments(args);

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                        .replace(R.id.content_frame, fragment).commit();

        // Update selected item and title, then close the drawer
        setDrawerItemChecked(position, true);
        setTitle(getResources().getStringArray(R.array.drawer_array)[position]);
        closeDrawer();

}

3)然后在层次结构的较低层(即Lower1.1)您应该执行“选择性向上”导航,在流程中重新创建任务堆栈

Selective Up 允许用户随意跳过应用的导航层次结构。应用程序应该将其视为处理来自不同任务的向上导航,替换当前任务堆栈(这就是您想要的!)使用 TaskStackBuilder 或类似的。这是唯一一种应该在任务的根 Activity 之外使用的抽屉式导航。

@Override
protected void onDrawerItemSelected(int position) {

        TaskStackBuilder.create(this)
                        .addParentStack(RootDrawerActivity.class)
                        .addNextIntent(new Intent(this, RootDrawerActivity.class)
                                        .putExtra(RootDrawerActivity.ARG_SORT, position))
                        .startActivities();

}

参考:

http://developer.android.com/training/implementing-navigation/ancestral.html https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android

【讨论】:

  • 这家伙应该得到声望。我花了几个小时寻找这样的概述,它很好地涵盖了整个主题!
  • 即使在未来这里也很有用。感谢您的精彩回复。
  • 很好的答案,但这不适用于 Android 4.4 设备。我最终传递了一个布尔值,然后在启动的活动中覆盖了 onBackPressed。
  • @Slickelito 为什么它不适用于 Android 4.4 设备?
  • 此答案中引用的speakerdeck 链接绝对是必读的!如果您的目标是 API 级别 16 及以上,大多数时候您甚至不需要做任何事情。该框架将为您处理一切。
猜你喜欢
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2013-08-11
  • 2020-05-07
  • 1970-01-01
相关资源
最近更新 更多