【问题标题】:Populate spinner items from database从数据库填充微调器项目
【发布时间】:2019-06-21 07:22:11
【问题描述】:

我无法让微调器正常处理从 SQLite 数据库中检索到的项目。我可以让项目显示在下拉列表中,但我无法选择它们。如果我用一个简单的字符串数组替换了项目(questAddViewModel.categorylist),那么微调器可以正常工作。我只是不知道如何让从数据库中填充的列表改为工作。

我正在使用 room 和 Dao 进行数据库调用。

更新:包含屏幕截图以供澄清。如果我单击第二张图片中的任何项目,屏幕将返回到第一张图片,微调器中不会显示任何选择的内容。如果我尝试像在注释代码中所做的那样将 selectedItem 分配给字符串

//questCategorySelected = parent.getItemAtPosition(pos).toString()

它会告诉我它是空的。

  1. ScreenShot with the Spinner (The Green Bar)

  2. ScreenShot with the Spinner showing the item in dropdown


这是我在片段中的微调器代码:

//Setup Spinner for Quest Category
        val categorySpinnerAdapter = ArrayAdapter(application, android.R.layout.simple_spinner_item, questAddViewModel.categorylist) //
                categorySpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        binding.addQuestCategory.adapter = categorySpinnerAdapter
        binding.addQuestCategory.onItemSelectedListener = object : AdapterView.OnItemSelectedListener
        {
            override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
                // An item was selected. You can retrieve the selected item using
                // parent.getItemAtPosition(pos)
                //questCategorySelected = parent.getItemAtPosition(pos).toString()
                //Toast.makeText(application, "${parent.getItemAtPosition(pos).toString()} <-In Selected", Toast.LENGTH_LONG).show();
            }
            override fun onNothingSelected(parent: AdapterView<*>) {
                // Another interface callback
            }
        }

这是我在 ViewModel 中的代码

private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
val categorylist = ArrayList<String>()

 init {
        populateCategorySpinner()
    }

    fun populateCategorySpinner()
    {
        uiScope.launch {
            populateCategorySpinnerList()
        }
    }

    private suspend fun populateCategorySpinnerList()
    {
        withContext(Dispatchers.IO)
        {
            val categorylistcursor = database.getQuestCategoryCursor()

            if (categorylistcursor.moveToFirst()) {
                do {
                    val category =
                        categorylistcursor.getString(categorylistcursor.getColumnIndexOrThrow("quest_category_name"))
                    categorylist.add(category);
                } while (categorylistcursor.moveToNext())
            }
            categorylistcursor.close();
        }
    }

这就是我在道中所拥有的

    @Query ( "SELECT * FROM t_ql_quest_category")
    fun getQuestCategoryCursor(): Cursor

我正在寻找一种解决方案来获取我从数据库光标中检索到的列表,以便能够在微调器中正确选择。

【问题讨论】:

  • 真正的问题是什么:没有显示 Toast 或 questCategorySelected = parent.getItemAtPosition(pos).toString() 错误?
  • 当我使用数据库中的列表时,程序似乎永远不会进入 onItemSelected。因此,当我尝试调用它时,我总是在 selectedItem 上得到一个空值。我可以在下拉列表中看到列表,但我在下拉列表中单击的项目在我单击后也未显示在微调器上。
  • 我从不使用 ViewModel,但尝试定义 questCategorySelected = (TextView)view 。这可能会有所帮助
  • questCategorySelected 是我定义的字符串。当我选择一个项目时,我试图用它来查看是否能得到任何价值。它返回空值。我已更新问题以包含此信息。谢谢!。一旦我将数据库列表中的列表替换为我在片段中定义的数组,完整的代码就会起作用。我试图弄清楚我做错了什么让数据库列表适合 ArrayAdapter 或了解这是否可能。
  • 您好 Rex,欢迎来到 StackOverflow!我认为您可能希望包含更多代码(适配器!)以确定那里发生了什么。您可能想告诉我们更多关于您调试的内容。似乎您正在使用 DataBinding,将此信息添加到问题中,因为它可能会产生影响。

标签: android kotlin android-arrayadapter android-spinner


【解决方案1】:

你有没有尝试改变 questCategorySelected = parent.getItemAtPosition(pos).toString()

questCategorySelected = (TextView) 视图

【讨论】:

    【解决方案2】:

    感谢 cmets 和回答。在阅读了 cmets 后,我实际上明白了这一点。问题似乎是由于对数据库的协程调用,数组实际上没有填充数据。这令人困惑,因为它显示在下拉列表中。在阅读了更多关于 LiveData 的内容并保持适配器更新并观察它之后,我解决了这个问题。我尝试了几种方法将数组从 ViewModel 传递给 Fragment,但似乎没有使用 LiveData,由于数据库调用协程,列表总是丢失。如果有人有更好的方法,欢迎提出建议!谢谢!

    以下是我的解决方案:

    片段

    //Setup Spinner for Quest Category with LiveData monitoring of the Category List
            var CategoryArray: Array<String>
            var categorySpinnerAdapter: ArrayAdapter<String>
    
            questAddViewModel.categorylist.observe(this, Observer
            {if (it != null && it.isNotEmpty()) {
                CategoryArray = toArray(questAddViewModel.categorylist.value!!)
                categorySpinnerAdapter = ArrayAdapter(application, android.R.layout.simple_spinner_item, CategoryArray) //
                categorySpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                binding.addQuestCategory.adapter = categorySpinnerAdapter
            }})
    
            binding.addQuestCategory.onItemSelectedListener = object : AdapterView.OnItemSelectedListener
            {
                override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
                    // An item was selected. You can retrieve the selected item using
                    // parent.getItemAtPosition(pos)
                }
                override fun onNothingSelected(parent: AdapterView<*>) {
                    // Another interface callback
                }
            }
    

    视图模型

    private val _categorylist = MutableLiveData<ArrayList<String>>()
        val categorylist: LiveData<ArrayList<String>>
            get() = _categorylist
    
     private suspend fun populateCategorySpinnerList()
        {
            withContext(Dispatchers.IO)
            {
                val categorylistcursor = database.getQuestCategoryCursor()
                val categorylistfromdb = ArrayList<String>()
    
                if (categorylistcursor.moveToFirst()) {
                    do {
                        val category =
                            categorylistcursor.getString(categorylistcursor.getColumnIndexOrThrow("quest_category_name"))
                        categorylistfromdb.add(category);
                    } while (categorylistcursor.moveToNext())
                }
                categorylistcursor.close();
                _categorylist.postValue(categorylistfromdb)
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-12
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多