Fragment 中的 Navigation.findNavController() 无法正常工作

Navigation.findNavController() in Fragment does not work properly

我正在尝试开发单一 activity 应用程序,该应用程序在特定条件下使用导航到我的主页片段中的相应片段(请参阅下面的代码片段)。但是当我以isLoggedIn == true条件开始申请时,出现异常:

2022-05-01 17:42:22.888 14974-14974/com.example.shercofaqapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.shercofaqapp, PID: 14974
java.lang.IllegalStateException: Fragment LoginFragment{d69320f} (2bebfc01-ce4e-435e-be4f-821b5d142eb8 id=0x7f0a0096) did not return a View from onCreateView() or this was called before onCreateView().
    at androidx.fragment.app.Fragment.requireView(Fragment.java:2008)
    at com.example.shercofaqapp.view.LoginFragment.onCreateView(LoginFragment.kt:47)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
    at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777)
    at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
    at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784)
    at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
    at android.app.Activity.performStart(Activity.java:7825)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

这是我的代码片段:

package com.example.shercofaqapp.view

import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.navigation.Navigation
import com.example.shercofaqapp.R
import com.example.shercofaqapp.databinding.FragmentLoginBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import kotlin.properties.Delegates

class LoginFragment : Fragment() {

    lateinit var binding: FragmentLoginBinding
    private var isLoggedIn by Delegates.notNull<Boolean>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val sharedPref = requireActivity()
            .getSharedPreferences("MyPreferences", Context.MODE_PRIVATE)
        val editor = sharedPref.edit()
        var isLoggingIn = false


        binding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_login, container, false)

        binding.apply {
            //Log in / sign up logic
            isLoggedIn = sharedPref.getBoolean("isLoggedIn", false)
            if (isLoggedIn) {
                Navigation.findNavController(requireView())
                    .navigate(R.id.action_loginFragment_to_garageFragment)
            }
        }
        return binding.root
    }
}

问题是:如何在onCreateView()return之前获取view用于导航呢?

我尝试使用 解决方案,但我不明白我应该向 .findNavController(...) 传递什么参数。

P.S。 NavHostFragment 在 MainActivity 中:

<?xml version="1.0" encoding="utf-8"?>
<layout
    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"
    tools:context=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/containerView"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

</layout>

根据 Navigate to a destination documentation, you should use the findNavController() Kotlin extension on Fragment, which is a convenience wrapper around calling NavHostFragment.findNavController(this):

binding.apply {
    //Log in / sign up logic
    isLoggedIn = sharedPref.getBoolean("isLoggedIn", false)
    if (isLoggedIn) {
        // Make sure to:
        // 1. Add a dependency on navigation-fragment-ktx in your build.gradle
        // 2. import androidx.navigation.fragment.findNavController
        findNavController()
            .navigate(R.id.action_loginFragment_to_garageFragment)
    }
}

findNavController(requireActivity()) .navigate(R.id.action_loginFragment_to_garageFragment)

使用此行代码,我认为对您有帮助

编辑: 如果您在片段中使用它,

Navigation.findNavController(getView()).navigate(R.id.action_loginFragment_to_garageFragment)