Kotlin 从片段中读取房间数据库

Kotlin read from room database in fragment

我用房间数据库编写了一个应用程序,但在读取数据并在我的线程中使用它时遇到了问题。

将表格视为:

表 1

| ID |  Name  |
| -- | ------ |
| 1  | first  |
| 2  | second |

表2

| ID | Name |  description  | table1_id|
|--- | ---- | ------------- |----------|
| 1  | test | not important |     2    |
| 2  | test | not important |     1    |

我可以毫无问题地显示来自 table2 的对象信息,因为它已传递给片段,但是当我尝试获取 Name 来自 ID 来自 table1 我无法这样做。我搜索了信息,但没有找到对我有帮助的信息。

我的代码:

private var _binding: FragmentXUpdateBinding? = null
private val binding get() = _binding!!

private lateinit var mXViewModel: XViewModel
private lateinit var mXTypeViewModel: XTypeViewModel
private val args by navArgs<XUpdateFragmentArgs>()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    _binding = FragmentXUpdateBinding.inflate(inflater, container, false)
    mXViewModel = ViewModelProvider(this)[XViewModel::class.java]
    mXTypeViewModel = ViewModelProvider(this)[XTypeViewModel::class.java]
    setHasOptionsMenu(true)

        val XType = getXTypeName(args.currentX.X_type_id)
        binding.XTypeText.text = XType


    binding.etXName.setText(args.currentX.name)
    binding.etXDescription.setText(args.currentX.description)

    binding.buttonUpdateX.setOnClickListener {
        updateItem()
        findNavController().navigate(my.food.R.id.action_XUpdateFragment_to_XListFragment)
    }

    return binding.root
}

private fun getXTypeName(id: Int): String {
  var XTypeString = ""
  mXTypeViewModel.readAllData.observe(viewLifecycleOwner) { type ->
      type?.forEach {
          if (it.id == id) {
              XTypeString = it.name
          }
      }
  }
  return XTypeString   //it returns "" since database thread is still ongoing
}

请注意倒数第二行的评论。

有什么方法可以解决我的头痛问题? 谢谢!!!!

问题是您试图在异步任务(来自 ViewModel 的 readAllData)完成之前检索 XTypeString。您应该将 XTypeText 的绑定移动到 observe 中,如下所示。请注意 bindXTypeText() 函数签名的变化。

private fun bindXTypeText(id: Int) {
  var XTypeString = ""
  mXTypeViewModel.readAllData.observe(viewLifecycleOwner) { type ->
      type?.forEach {
          if (it.id == id) {
              XTypeString = it.name
          }
      }

      binding.XTypeText.text = XTypeString //moved the assignment of XtypeText here.
  }
}