Android Navigation Component Activity Intent Flags

Pop*_*ash 4 android android-architecture-navigation android-navigation-graph

I have created a navigation action from a fragment to an activity, but I have no way of clearing the back stack. When I execute the navigation action from my fragment to my new activity, and I press the back button, I am taken back to the previous activity and previous fragment. I have no way of setting Intent flags, using the navigation graph, to clear the previous activity from the back stack.

<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>
Run Code Online (Sandbox Code Playgroud)

PopTo and Inclusive flags have no effect on the back button when navigating from a fragment to a new activity, even though they can be set in the graph editor. I am able to navigate, using the back button, to the previous activity that I no longer want in the stack.

Before migrating to the navigation graph, I could just specify this behavior with Intent flags:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Run Code Online (Sandbox Code Playgroud)

How can I achieve the same thing with the navigation graph?

Abd*_*bri 7

参考法蒂赫的回答

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)
Run Code Online (Sandbox Code Playgroud)

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

  1. FLAG_ACTIVITY_CLEAR_TASK:将活动设置为根任务。与...一起使用
  2. FLAG_ACTIVITY_NEW_TASK:将该活动视为启动器活动。
  3. FLAG_ACTIVITY_REORDER_TO_FRONT:将活动置于前面。仅当堆栈上有其他活动并且您不想清除它时才使用此选项。


Mau*_*ker 5

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

例如:

<action
    android:id="@+id/action_frag_to_myActivity"
    app:destination="@id/myActivity"
    app:popUpTo="@id/myActivity" />
Run Code Online (Sandbox Code Playgroud)

现在,您可以将参数作为意图附加项传递给 Activity,因此您可以利用它使目标 Activity 执行“脏工作”并为您清除返回堆栈。

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

<activity
    android:id="@+id/myActivity"
    android:name="com.dummy.MyActivity"
    android:label="activity_my" />
Run Code Online (Sandbox Code Playgroud)

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

 <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>
Run Code Online (Sandbox Code Playgroud)

然后,一旦你调用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()
}
Run Code Online (Sandbox Code Playgroud)

请记住,您可以修改参数并自定义您想要在目标活动上执行的操作。您还可以在导航到该值后修改该值。你可以在文档中阅读更多关于它的信息

  • 男人真痛苦。我认为我们需要一份 Android RFE。 (2认同)