【问题标题】:lateinit property mUserViewModel has not been initializedlateinit 属性 mUserViewModel 尚未初始化
【发布时间】:2020-11-20 12:56:28
【问题描述】:

我正在尝试读取我的数据库,因此我创建了一个编辑文本,我将在其中输入一个用户名和一个允许我搜索用户的按钮,但我在 ListFragment 类中显示错误:Fragment() ,表示lateinit属性mUserViewModel尚未初始化,请帮助我:(。

//实体

@Entity(tableName = "user_table")
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val firstName: String,
    val lastName: String,
    val age: Int
)

//道

@Dao
interface UserDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun addUser(user: User)
    @Query("SELECT * FROM user_table where firstName LIKE :search LIMIT 1")
    suspend fun readAllData(search : String) : User

}

//用户存储库

class UserRepository(private val userDao: UserDao) {
    suspend fun readAllData(user: String):User{
       return userDao.readAllData(user)
    }
}

//用户视图模型

class UserViewModel(application: Application): AndroidViewModel(application) {
    
   private lateinit var repository:UserRepository
    
    fun search( search : String):User{
        viewModelScope.launch {
            repository.readAllData(search)
        }
  
        return search(String())
    }

}

}

//类

class ListFragment : Fragment() {
    //erro(lateinit property mUserViewModel has not been initialized)
                lateinit var mUserViewModel:UserViewModel
                override fun onCreateView(
                    inflater: LayoutInflater, container: ViewGroup?,
                    savedInstanceState: Bundle?
                ): View? {
                    // Inflate the layout for this fragment
                    val view = inflater.inflate(R.layout.fragment_list, container, false)
            
                    val name = view.editTextTextNameee.text.toString()
                   val prueba = mUserViewModel.search(name)
            
                    if (prueba!=null){
            
                        textView1.text = prueba.firstName
                        textView2.text = prueba.lastName
                        textView3.text = prueba.age.toString()
                    }else {
                        Toast.makeText(context, " Unregistered use", Toast.LENGTH_SHORT).show()
                    }
            
            
                    view.floatingActionButton.setOnClickListener {
                        findNavController().navigate(R.id.action_listFragment_to_addFragment)
                    }
            
                    return view
                }
            }

【问题讨论】:

    标签: android-studio android-room android-livedata kotlin-coroutines android-viewmodel


    【解决方案1】:

    lateinit 未初始化属性的原因是您尚未创建 ViewModel 实例。你可以试试这个

    viewModel = ViewModelProvider(requireParentFragment(), factory).get(UserViewModel::class.java)
    

    //工厂将是视图模型的实例

    你可以观察到onviewCreated()的livedata变化

    【讨论】:

      【解决方案2】:

      这是正常的,因为你的 Dao 返回一个 LiveData 所以当你观察这个数据时,返回值是一个 List 而不仅仅是一个 User。我不知道你想做什么。但你必须:

      mUserViewModel.searchResult.observe(viewLifecycleOwner, Observer { 
                   
                    textViewName.text = it.name
                    textViewLastName.text = it.lastname
                    textViewAge.text = it.age
                })
      

      您的查询将是:

      @Query("SELECT * FROM user_table where name LIKE :search LIMIT 1") 
      suspend fun searchUser(search : String) : User
      

      并在您的 mUserViewModel 中创建一个值 searchResult 和一个方法 search:

      fun search(val search : String){
      viewModelScope.launch {
          searchResult.postValue(dao.searchUser(search))
      }
      
      }
      

      【讨论】:

      • 嗨,我尝试读取我的数据库,因此我创建了一个编辑文本,我将在其中输入用户名和一个允许我搜索用户的按钮,但从我看到的一切都是错误的,因为它通过视频教程支持我,我请求您在纠正我的数据库方面提供宝贵的帮助。
      • @JorgeLeonardo 。也许我能理解。
      • 我已经重组了我的数据库,但我使用了主线程,你能解释一下不使用它的最佳做法吗?
      • @JorgeLeonardo ,太长了。看到这个:developer.android.com/codelabs/…
      猜你喜欢
      • 2017-03-03
      • 1970-01-01
      • 2020-12-31
      • 2021-06-11
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多