web-dev-qa-db-ja.com

Androidナビゲーションコンポーネントの戻るボタンが機能しない

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>

enter image description here

上の画像で、強調表示されている矢印(左側)は、問題のあるナビゲーションアクションです。

私の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>
4

ナビゲーションが完了したら、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のままであり、前のフラグメントに戻ることができないことです。

0
Shah91n

OnCreateViewでonBackPressedを呼び出す

private fun onBackPressed() {
    requireActivity().onBackPressedDispatcher.addCallback(this) {
        //Do something
    }
}
0
Dino Sunny

次のようなナビゲーションコンポーネントで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()
}
}
0
nirazverma