#android #android-navigation #multi-module
#Android #android-навигация #многомодульный
Вопрос:
Есть ли какой-либо способ перейти к определенному фрагменту из другого динамического модуля и не перейти к месту назначения start? Если нет, каковы альтернативы?
<fragment
android:id="@ id/loginFragment"
android:name="com.example.feature.login.presentation.LoginFragment"
android:label="LoginFragment">
<action
android:id="@ id/actionLoginToHome"
app:destination="@id/featureHomeNavGraph" />
</fragment>
<include-dynamic
android:id="@ id/featureHomeNavGraph"
app:graphResName="feature_home_nav_graph"
app:moduleName="feature_home" />
Хотя этот код работает нормально, он перенаправляет меня к месту назначения start, но мне нужно перейти к другому.
Ответ №1:
Решение 1. Перейдите к определенному фрагменту и не используйте <include-dynamic>
<fragment
android:id="@ id/profileDetailsFragment"
android:name="com.example.feature.profiles.presentation.details.ProfileDetailsFragment"
android:label="Profile Details"
app:moduleName="feature_profiles" />
Решение 2. Создайте новый XML-график с другим начальным назначением.
Ответ №2:
Хороший способ сделать это для встроенных навигационных графиков — иметь пустой фрагмент навигации. Вы получаете свое действие для перехода к этому фрагменту, а затем отправляете ему аргументы о том, куда перейти дальше. Некоторый пример кода:
class NavigatorFragment : Fragment() {
companion object {
const val REQUEST_PAGE_NAME = "REQUEST_PAGE_NAME"
const val PAGE_TYPE_ACTIVATE_CARD = "PAGE_TYPE_ACTIVATE_CARD"
const val PAGE_TYPE_CREDIT_LIMIT = "PAGE_TYPE_CREDIT_LIMIT"
const val PAGE_TYPE_SCC_HUB = "PAGE_TYPE_SCC_HUB"
const val PAGE_TYPE_ABOUT_CARD = "about_card"
const val PAGE_TYPE_MAKE_PAYMENT = "PAGE_TYPE_MAKE_PAYMENT"
fun createBundle(pageName: String) =
Bundle().apply {
putString(REQUEST_PAGE_NAME, pageName)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
when (arguments?.getString(REQUEST_PAGE_NAME)) {
PAGE_TYPE_ACTIVATE_CARD ->
findNavController().navigate(R.id.to_activateSecuredCard)
PAGE_TYPE_CREDIT_LIMIT ->
findNavController().navigate(R.id.to_creditLimit)
PAGE_TYPE_ABOUT_CARD ->
findNavController().navigate(R.id.to_aboutSecuredCard, arguments)
PAGE_TYPE_SCC_HUB ->
findNavController().navigate(R.id.to_sccHub)
PAGE_TYPE_MAKE_PAYMENT ->
findNavController().navigate(R.id.to_sccMakePayment)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: FragmentSecuredCardNavigatorBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_secured_card_navigator, container, false)
binding.lifecycleOwner = viewLifecycleOwner
if (findNavController()
.currentDestination.toString()
.contains(this.javaClass.name)
){
findNavController().popBackStack()
}
return binding.root
}
}
основная навигация:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@ id/home_dashboard_fragment">
<include app:graph="@navigation/nav_graph_secured_card" />
<!-- rest of navigation graph-->
.....
</navigation>
защищенная навигация по картам:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/nav_root_secured_card"
app:startDestination="@id/securedCardNavigator">
<fragment
android:id="@ id/securedCardNavigator"
android:name="com.greendotcorp.securedcard.fragment.NavigatorFragment">
<action
android:id="@ id/to_activateSecuredCard"
app:destination="@ id/activateSecuredCard"
app:popUpTo="@ id/securedCardNavigator"
app:popUpToInclusive="true" />
</fragment>
</navigation>
Переход к защищенной навигации по картам:
findNavController().navigate(R.id.nav_root_secured_card, NavigatorFragment.createBundle(NavigatorFragment.PAGE_TYPE_SCC_HUB))