Android=でナビゲーションコンポーネントを使用しています。最初に6つのフラグメントを設定しました。問題は、新しいフラグメント(ProfileFragment)を追加したときです。
開始先からこの新しいフラグメントに移動するときに、ネイティブの戻るボタンを押しても、現在のフラグメントがポップオフされません。代わりに、それは私がいるフラグメントにとどまります。戻るボタンは何もしません。
これが私のnavigation.xmlです:
<?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/dashboard_navigation"
app:startDestination="@id/dashboardFragment"
>
<fragment
Android:id="@+id/dashboardFragment"
Android:name="com.devssocial.localodge.ui.dashboard.ui.DashboardFragment"
Android:label="DashboardFragment"
>
<action
Android:id="@+id/action_dashboardFragment_to_newPostFragment"
app:destination="@id/newPostFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
<action
Android:id="@+id/action_dashboardFragment_to_notificationsFragment"
app:destination="@id/notificationsFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
<action
Android:id="@+id/action_dashboardFragment_to_mediaViewer"
app:destination="@id/mediaViewer"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
<action
Android:id="@+id/action_dashboardFragment_to_postDetailFragment"
app:destination="@id/postDetailFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
====================== HERE'S THE PROFILE ACTION ====================
<action
Android:id="@+id/action_dashboardFragment_to_profileFragment"
app:destination="@id/profileFragment"
app:enterAnim="@anim/slide_in_up"
app:exitAnim="@anim/slide_out_down"
app:popEnterAnim="@anim/slide_in_up"
app:popExitAnim="@anim/slide_out_down"
/>
=====================================================================
</fragment>
<fragment
Android:id="@+id/profileFragment"
Android:name="com.devssocial.localodge.ui.profile.ui.ProfileFragment"
Android:label="fragment_profile"
tools:layout="@layout/fragment_profile"
/>
</navigation>
上の画像で、強調表示されている矢印(左側)は、問題のあるナビゲーションアクションです。
私のFragmentコードでは、次のようにナビゲートしています:
findNavController().navigate(R.id.action_dashboardFragment_to_profileFragment)
他のナビゲーションアクションは意図したとおりに機能しています。しかし、何らかの理由で、この新しく追加されたフラグメントは意図したとおりに動作しません。
ProfileFragmentに移動したときと、戻るボタンを押したときに表示されるログはありません。
何か不足していますか?または私のアクション/フラグメント設定に何か問題がありますか?
編集:私はProfileFragmentでは何もしません。そのコードは次のとおりです。
class ProfileFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_profile, container, false)
}
}
そして、ナビゲーションホストを含む私のactivity xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<fragment
Android:id="@+id/dashboard_navigation"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
Android:name="androidx.navigation.fragment.NavHostFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:navGraph="@navigation/dashboard_navigation"
app:defaultNavHost="true"/>
</FrameLayout>
ナビゲーションが完了したら、MutableLiveDataをnullに設定する必要があります。
例えば
private val _name = MutableLiveData<String>()
val name: LiveData<String>
get() = _name
fun printName(){
_name.value = "John"
}
fun navigationComplete(){
_name.value = null
}
ここで、フラグメントの「名前」を監視していて、名前がJohnになったらナビゲーションを行っているとします。
viewModel.name.observe(viewLifecycleOwner, Observer { name ->
when (name) {
"John" -> {
this.findNavController() .navigate(BlaBlaFragmentDirections.actionBlaBlaFragmentToBlaBlaFragment())
viewModel.navigationComplete()
}
}
})
これで、戻るボタンは問題なく動作します。
Snackbarメッセージやナビゲーションイベントなど、一部のデータはほぼ一度しか使用されないため、使用が終了したら値をnullに設定する必要があります。
問題は、_nameの値がtrueのままであり、前のフラグメントに戻ることができないことです。
OnCreateViewでonBackPressedを呼び出す
private fun onBackPressed() {
requireActivity().onBackPressedDispatcher.addCallback(this) {
//Do something
}
}
次のようなナビゲーションコンポーネントでsetupActionBarWithNavControllerを使用している場合:
setupActionBarWithNavController(findNavController(R.id.fragment))
次に、メインアクティビティでこのメソッドをオーバーライドして構成します。
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragment)
return navController.navigateUp() || super.onSupportNavigateUp()
}
私のMainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupActionBarWithNavController(findNavController(R.id.fragment))
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragment)
return navController.navigateUp() || super.onSupportNavigateUp()
}
}