7

我已经创建了从片段到活动的导航操作,但我无法清除后台堆栈。当我执行从片段到新活动的导航操作并按下后退按钮时,我会回到上一个活动和上一个片段。我无法使用导航图设置 Intent 标志来清除后台堆栈中的先前活动。

<fragment
    android:id="@+id/loginFragment"
    android:name="com.myapp.auth.LoginFragment"
    android:label="login_fragment"
    tools:layout="@layout/login_fragment" >
    <action
        android:id="@+id/action_loginFragment_to_webActivity"
        app:destination="@id/webActivity"
        app:popUpTo="@id/loginFragment"
        app:popUpToInclusive="true" />
</fragment>
<activity
    android:id="@+id/webActivity"
    android:name="com.myapp.web.WebActivity"
    android:label="activity_web"
    tools:layout="@layout/activity_web" >
</activity>

从片段导航到新活动时, PopToInclusive标志对后退按钮没有影响,即使它们可以在图形编辑器中设置。我可以使用后退按钮导航到堆栈中不再需要的上一个活动。

在迁移到导航图之前,我可以使用 Intent 标志指定此行为:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

如何使用导航图实现相同的目标?

4

5 回答 5

4

我不得不破解同样的问题。要解决这个问题,您必须做的第一件事是创建一个操作来导航到 Activity,就像您已经完成的那样。

例如:

<action
    android:id="@+id/action_frag_to_myActivity"
    app:destination="@id/myActivity"
    app:popUpTo="@id/myActivity" />

现在,您可以将参数作为 Intent Extras 传递给 Activity,因此您可以利用它来使目标 Activity 执行“脏工作”并为您清除后台堆栈。

假设您的导航图中有这个活动标签:

<activity
    android:id="@+id/myActivity"
    android:name="com.dummy.MyActivity"
    android:label="activity_my" />

您可以在其中添加一个参数并添加一个默认值。例如:

 <activity
    android:id="@+id/myActivity"
    android:name="com.dummy.MyActivity"
    android:label="activity_my">

        <argument
            android:name="clearBackstack"
            app:argType="boolean"
            android:defaultValue="true" />

</activity>

然后,一旦你调用findNavController().navigate(R.id.myActivity)它,它就会传递一个额外的意图,"clearBackstack"其中包含你可以在 ActivityonCreate()方法中读取的密钥。类似于下面的示例。

我的活动.kt

private val EXTRA_LOGOUT = "clearBackstack"

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (intent.extras?.getBoolean(EXTRA_LOGOUT) == true) {
        clearBackstack()
    } else {
        setContentView(R.layout.activity_my)
    }
}

private fun clearBackstack() {
    startActivity(Intent(this, MyActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
    })

    finish()
}

请记住,您可以修改参数并自定义要在目标 Activity 上执行的操作。导航到该值后,您也可以修改该值。您可以在 docs中阅读有关它的更多信息。

于 2020-01-17T22:28:17.023 回答
4

参考法提赫的回答

val extras = ActivityNavigator.Extras.Builder()
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        .build()
findNavController().navigate(BlaBlaActivityDirections.actionFooBarToBlaBlaActivity(), extras)

注意您需要将这些标志添加到活动堆栈:

  1. FLAG_ACTIVITY_CLEAR_TASK:将活动设置为根任务。与
  2. FLAG_ACTIVITY_NEW_TASK:将活动视为启动器活动。
  3. FLAG_ACTIVITY_REORDER_TO_FRONT: 把活动带到前面。仅当堆栈上有其他活动并且不想清除它时才使用此选项。
于 2020-08-24T18:08:37.113 回答
0

您可以在导航定义中从操作元素控制诸如 singleTop 之类的属性。

这些属性在导航编辑器中也可用。

在此处输入图像描述

于 2020-05-15T21:01:05.960 回答
0

您可以将意图标志添加到导航器附加功能。

val extras = ActivityNavigator.Extras.Builder()
   // Add your flags 
   .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
   .build()

// Navigate with extras 
findNavController().navigate(destination, extras)

ActivityNavigator.navigate()您可以从源代码中检查意图标志的处理方式

或者,如果您要设置的唯一标志是FLAG_ACTIVITY_SINGLE_TOP.

val navOptions = NavOptions.Builder().setLaunchSingleTop(true).build()
findNavController().navigate(destination, navOptions)

您可以检查如何ActivityNavigator.navigate()源代码签入导航选项

于 2020-07-30T09:00:03.190 回答
-4

如果您要从一项活动转移到另一项活动。

我就是这样解决了同样的问题。我希望它有所帮助。

firstIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
于 2020-01-07T19:40:05.330 回答