Кнопка возврата на панель инструментов скрыта из-за начального пункта назначения

Фон

Я пытаюсь использовать одно действие для каждого модуля, где каждое действие имеет свой собственный навигационный график. Таким образом, навигация переходит от действия в одном модуле динамических функций к другому действию в другом модуле динамических функций.

Feature1/ActivityA -> Feature2/ActivityB

ActivityA просто вызывает базовый метод startActivity для запуска ActivityB.

Проблема

Поскольку ActivityB технически имеет свой фрагмент в начальной точке назначения. Кнопка «Назад» не отображается, хотя у меня есть ActivityA в моем рюкзаке. Есть ли способ обойти эту проблему?

PS: поскольку ActivityA и ActivityB находятся в двух отдельных модулях, я избегаю их размещения под одним графиком. Для перехода активности я просто вызываю startActivity, создавая intent с помощью className.

Обновление. Даже если я использую навигационный контроллер для перехода от фрагмента ActivityA к ActivityB, проблема все еще существует.

ActivityB.xml

</layout>

    <LinearLayout
        xmlns:android = "http://schemas.android.com/apk/res/android"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"
        android:orientation = "vertical">

        <androidx.appcompat.widget.Toolbar
            android:id = "@+id/main_toolbar"
            app:navigationIcon = "@drawable/ic_back"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            app:title = "@string/title" />

        <androidx.fragment.app.FragmentContainerView
            android:id = "@+id/host_container"
            android:name = "androidx.navigation.fragment.NavHostFragment"
            android:layout_width = "match_parent"
            android:layout_height = "0dp"
            android:layout_weight = "1"
            app:defaultNavHost = "true"
            app:navGraph = "@navigation/landing_graph" />
    </LinearLayout>

</layout>

ActivityB.kt

internal class ActivityB : AppCompatActivity() {

    private var navController : NavController? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val toolbar = binding.mainToolbar
        navController = supportFragmentManager.findFragmentById(R.id.host_container) as NavHostFragment).navController
        setSupportActionBar(toolbar)
        toolbar.setNavigationOnClickListener { onBackPressed() }
        toolbar.setupWithNavController(navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
}

Landing_graph.xml

<?xml version = "1.0" encoding = "utf-8"?>
<navigation xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    xmlns:android = "http://schemas.android.com/apk/res/android"
    app:startDestination = "@id/blankFragment">
    <fragment
        android:id = "@+id/blankFragment"
        android:name = "com.example.cashdog.cashdog.BlankFragment"
        android:label = "Blank"
        tools:layout = "@layout/fragment_blank" />

    <fragment
        android:id = "@+id/blankFragment2"
        android:name = "com.example.cashdog.cashdog.BlankFragment2"
        android:label = "Blank"
        tools:layout = "@layout/fragment_blank_2" />
</navigation>

Есть ли причина, по которой вы используете отдельные действия, когда Навигация специально поддерживает модули динамических функций в одном графе?

ianhanniballake 11.12.2020 08:23

с модулями с динамическими функциями глубокие ссылки не поддерживаются, это основная причина.

user3354265 11.12.2020 08:25
3
2
916
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Согласно руководству AppBarConfiguration, если вы хотите, чтобы кнопка «Вверх» отображалась во всех пунктах назначения, даже в вашем начальном пункте назначения, вам следует использовать конструктор AppBarConfiguration, который принимает список пунктов назначения верхнего уровня. При передаче пустого набора в каждом пункте назначения будет отображаться кнопка «Вверх».

Поэтому вы ActivityB должны быть:

internal class ActivityB : AppCompatActivity() {

    private var navController : NavController? = null
    private val appBarConfiguration = AppBarConfiguration(emptySet())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val toolbar = binding.mainToolbar
        navController = supportFragmentManager.findFragmentById(R.id.host_container) as NavHostFragment).navController
        setSupportActionBar(toolbar)
        // You must always use setupActionBarWithNavController
        // when using setSupportActionBar()
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
}

Одна из проблем, возникающих при передаче emptySet, заключается в том, что android:label для начального пункта назначения не подбирается в первый раз при загрузке фрагмента startDestination. Почувствуйте, что единственный обходной путь — вызвать setTitle из фрагмента startDestination, когда он загружен.

user3354265 12.12.2020 04:27

Набор пунктов назначения верхнего уровня не используется при определении того, установлена ​​ли метка (она всегда установлена ​​для каждого пункта назначения). Похоже, у вас есть какая-то другая проблема.

ianhanniballake 12.12.2020 05:19

Если я не прохожу emptySet, то заголовок отображается без кнопки «Назад», потому что он выбирает android:label из графика навигации, но когда я прохожу emptySet, он выбирает имя моего приложения в качестве метки.

user3354265 12.12.2020 06:31

Лично я не вижу причин, по которым у вас на панели инструментов должно быть app:title = "@string/title", если вы используете android:label на своем графике. Даже учитывая, что согласно исходному коду, заголовок устанавливается безоговорочно, независимо от того, какой набор вы передаете.

ianhanniballake 12.12.2020 06:45

Я меняю title динамически, то есть пытаюсь сохранить одно действие для каждого функционального модуля. Таким образом, одно действие может иметь разные навигационные графы (т. е. разные начальные пункты назначения). Я буду использовать setTitle через фрагмент в качестве обходного пути. Спасибо за помощь, очень ценю это.

user3354265 12.12.2020 07:04

я думаю, что emptyset решил проблему. Ty

kondal 21.02.2022 11:55

Другие вопросы по теме