Я пытаюсь использовать одно действие для каждого модуля, где каждое действие имеет свой собственный навигационный график. Таким образом, навигация переходит от действия в одном модуле динамических функций к другому действию в другом модуле динамических функций.
Feature1/ActivityA -> Feature2/ActivityB
ActivityA просто вызывает базовый метод startActivity
для запуска ActivityB.
Поскольку ActivityB
технически имеет свой фрагмент в начальной точке назначения. Кнопка «Назад» не отображается, хотя у меня есть ActivityA
в моем рюкзаке. Есть ли способ обойти эту проблему?
PS: поскольку ActivityA
и ActivityB
находятся в двух отдельных модулях, я избегаю их размещения под одним графиком. Для перехода активности я просто вызываю startActivity
, создавая intent
с помощью className
.
Обновление. Даже если я использую навигационный контроллер для перехода от фрагмента ActivityA к ActivityB, проблема все еще существует.
</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>
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()
}
}
<?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>
с модулями с динамическими функциями глубокие ссылки не поддерживаются, это основная причина.
Согласно руководству 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, когда он загружен.
Набор пунктов назначения верхнего уровня не используется при определении того, установлена ли метка (она всегда установлена для каждого пункта назначения). Похоже, у вас есть какая-то другая проблема.
Если я не прохожу emptySet
, то заголовок отображается без кнопки «Назад», потому что он выбирает android:label
из графика навигации, но когда я прохожу emptySet
, он выбирает имя моего приложения в качестве метки.
Лично я не вижу причин, по которым у вас на панели инструментов должно быть app:title = "@string/title"
, если вы используете android:label
на своем графике. Даже учитывая, что согласно исходному коду, заголовок устанавливается безоговорочно, независимо от того, какой набор вы передаете.
Я меняю title
динамически, то есть пытаюсь сохранить одно действие для каждого функционального модуля. Таким образом, одно действие может иметь разные навигационные графы (т. е. разные начальные пункты назначения). Я буду использовать setTitle
через фрагмент в качестве обходного пути. Спасибо за помощь, очень ценю это.
я думаю, что emptyset решил проблему. Ty
Есть ли причина, по которой вы используете отдельные действия, когда Навигация специально поддерживает модули динамических функций в одном графе?