无法填充 ArrayList 类型的 MutableLiveData,结果始终为 null

Cannot fill a MutableLiveData of type ArrayList, outcome is always null

我正在做一个问答游戏,我想将一些 ID 存储在 MutableLiveData 数组列表中。因此,我创建了一个函数来循环数据库中的所有文档并将每个 ID 添加到数组列表中。但是结果总是空的。我不明白我哪里出错了?

我正在使用 MVVM 结构

游戏视图模型:

class GameViewModel : ViewModel() {

// database instance
val db = FirebaseFirestore.getInstance()

// the current category
private val _category = MutableLiveData<String>()
val category: LiveData<String>
    get() = _category

// the list of questionIds of the selected category
private val _questionIdsArray = MutableLiveData<ArrayList<Long>>()
val questionIdsArray: LiveData<ArrayList<Long>>
    get() = _questionIdsArray

// the current question
private val _question = MutableLiveData<String>()
val question: LiveData<String>
    get() = _question


/**
 * Set Current Category
 */
fun SetCategory (categoryName: String){
    _category.value = categoryName
}

/**
 * Get the list of QuestionIds
 */
fun GetListQuestionIds() {
    db.collection("questions")
        .whereEqualTo("category", "$_category")
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents) {
                _questionIdsArray.value?.add(document.data["questionid"] as Long)
                Log.d("GetSize","${_questionIdsArray.value?.size}")
            }
            Log.d("GetSize2","${_questionIdsArray.value?.size}")
        }
        .addOnFailureListener { exception ->
            Log.w("errorforloop", "Error getting documents: ", exception)
        }
}
/**
 * Get a Question
 */
fun GetQuizQuestion() {
    Log.d("retro","${_questionIdsArray.value?.size}")
    db.collection("questions")
        .whereEqualTo("category", "$_category")
        .whereEqualTo("questionid", "${_questionIdsArray.value?.get(0)}")
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents) {
                _question.value = document.data["question"].toString()
            }
        }
        .addOnFailureListener { exception ->
            Log.w("err", "Error getting documents: ", exception)
        }
}

游戏片段:

class GameFragment : Fragment() {

private lateinit var viewModel: GameViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val binding = FragmentGameBinding.inflate(inflater)

    // Get the viewModel
    viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
    binding.lifecycleOwner = this

    // Set the viewModel for DataBinding - this allows the bound layout access to all of the data in the VieWModel
    binding.gameviewModel = viewModel

    //arguments passed
    val selectedCategory = arguments?.getString("selectedCategory")!!

    //set current category so that the viewModel can use it
    viewModel.SetCategory(selectedCategory)

    viewModel.GetListQuestionIds()
    viewModel.GetQuizQuestion()

    return binding.root
}

如果有人能赐教...

你的问题

您没有初始化数组。这是您的代码:

// the list of questionIds of the selected category
private val _questionIdsArray = MutableLiveData<ArrayList<Long>>()
val questionIdsArray: LiveData<ArrayList<Long>>
    get() = _questionIdsArray

这声明了一个 ArrayList<Long> 类型的 MutableLiveData,但是 没有初始化它所以它的 value 默认为 null .

在您的 for 循环中,您有条件地添加项目:

_questionIdsArray.value?.add(document.data["questionid"] as Long)

当然 value 从未被初始化,所以它是空的,所以 add 是空操作(什么都不做)。

解决方案

只要确保在某个时候初始化实时数据对象即可。

您可以在声明中内联执行此操作:

// the list of questionIds of the selected category
private val _questionIdsArray = MutableLiveData<ArrayList<Long>>(arrayListOf())
val questionIdsArray: LiveData<ArrayList<Long>>
    get() = _questionIdsArray

或者在您尝试填充列表的过程中:

    .addOnSuccessListener { documents ->
        val idsArray = arrayListOf<Long>() // Non-null list to add to
        for (document in documents) {
            idsArray.add(document.data["questionid"] as Long)
            Log.d("GetSize","${idsArray.size}")
        }

        _questionIdsArray.value = idsArray // Now set live data with a valid list
        Log.d("GetSize2","${_questionIdsArray.value?.size}")
    }