Kotlin:切换片段时未初始化lateinit属性userDatabase

问题描述

我有一个带有三个标签和四个片段的活动。在其中一个选项卡(“配置文件”选项卡)上,有一个片段(ProfileFragment),该片段具有一个按钮,用于将用户重定向到另一个片段(EditorFragment)以编辑用户配置文件

class ProfileFragment : Fragment() {
   
 ...

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

        val v = inflater.inflate(R.layout.fragment_profile,container,false)

        val btn = v.findViewById<View>(R.id.editProfileButton) as Button

        btn.setonClickListener {
            val fragment = EditorFragment()
            val fragmentManager = activity!!.supportFragmentManager
            val transaction = fragmentManager.beginTransaction()
            transaction.replace(R.id.fragmentContainer,fragment)

           transaction.addToBackStack(null)
            transaction.commit()
        }
        return v
    }

EditorFragment也属于“个人资料”标签

        class EditorFragment : Fragment() {
        
            private lateinit var userDatabase: DatabaseReference
            private var callback: AppCallback? = null
    
        fun setCallback(callback: AppCallback) {
            this.callback = callback
            userId = callback.onGetUserId()
            userDatabase = callback.getUserDatabase().child(userId)
        }


        override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
            super.onViewCreated(view,savedInstanceState)

            populateInfo(view)
        }

    
       fun populateInfo(view: View) {
        userDatabase.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(p0: DataSnapshot) {
             ...
            }

当我首先打开EditorFragment时,一切 进行得很好,但是当我进入ProfileFragment并尝试使用按钮时 重定向到Editor Fragment,应用崩溃。

错误

lateinit property userDatabase has not been initialized
at com.example.app.fragments.EditorFragment.populateInfo(EditorFragment.kt:138)

在EditorFragment populateInfo()上引用此行:

userDatabase.addListenerForSingleValueEvent(object : ValueEventListener {

可能有用的附加信息:

主要活动:

class MainActivity : AppCompatActivity(),MainCallback {
             
    private lateinit var userDatabase: DatabaseReference
    private var profileFragment: ProfileFragment? = null
    private var editorFragment: EditorFragment? = null

    ...

        navigationTabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
        ...

            override fun onTabSelected(tab: TabLayout.Tab?) {
                when(tab) {
                    profileTab -> {
                        if (profileFragment == null) {
                            profileFragment = ProfileFragment()
                            profileFragment!!.setCallback(this@MainActivity)
                        }
                        replaceFragment(profileFragment!!)

                        if (editorFragment == null) {
                            editorFragment = EditorFragment()
                            editorFragment!!.setCallback(this@MainActivity)
                        }
                        replaceFragment (editorFragment!!)
                    }
         ...


     fun replaceFragment(fragment: Fragment){
         supportFragmentManager.beginTransaction()
        .replace(R.id.fragmentContainer,fragment)
        .commit()
     }

解决方法

当您优先使用EditorFragment来首先打开inTabSelectListener时触发,从而调用初始化您的数据库的 setCallBack ;当您首先打开ProfileFragment时,它不会触发onTabSelectedListener,因此不会调用您的 setCallBack ,它不会初始化您的数据库。让我知道它是否可以帮助您解决问题。