Не удается заполнить счетчик данными из базы данных?

#android #kotlin #android-fragments #android-room

#Android #kotlin #android-фрагменты #android-комната

Вопрос:

Я пытаюсь заполнить счетчик данными, используя room, я не получаю ошибок, но мой счетчик ничего не отображает. Я думаю, это может быть как-то связано с тем, как я вызываю initFirstUnitSpinnerData() в моем методе onCreateView? Но мне не повезло. Я использую kotlin.

Заранее благодарю.

DAO:

  @Query("SELECT firstUnit FROM conversion_table WHERE category LIKE :search")
 fun getByCategory(search: String): LiveData<List<String>>
 

Репозиторий:

 fun getByCategory(search: String): LiveData<List<String>>{
    return conversionsDAO.getByCategory(search)
}
 

Просмотр модели:

 fun getByCategory(search: String): LiveData<List<String>> {
        return repository.getByCategory(search)
    
}
 

Фрагмент:

 class UnitsFragment : Fragment() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    }

private lateinit var mConversionsViewModel: ConversionsViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view = inflater.inflate(R.layout.fragment_units, container, false)
    mConversionsViewModel = ViewModelProvider(this).get(ConversionsViewModel::class.java)


    initFirstUnitSpinnerData()
    return view
    }

private fun initFirstUnitSpinnerData() {
    val spinnerFirstUnit = view?.findViewById<Spinner>(R.id.firstUnitSpinner)

    if (spinnerFirstUnit != null) {
        val allConversions = context?.let {
            ArrayAdapter<Any>(it, R.layout.support_simple_spinner_dropdown_item)
        }
        mConversionsViewModel.getByCategory("Distance")
            .observe(viewLifecycleOwner, { conversions ->
                conversions?.forEach {
                    allConversions?.add(it)
                }
            })
        spinnerFirstUnit.adapter = allConversions

        spinnerFirstUnit.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                Toast.makeText(requireContext(), "$allConversions", Toast.LENGTH_LONG).show()
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {
                
            }
        }
    }
}


}
 

Ответ №1:

Это то, что вы действительно должны отлаживать — щелкните по левому желобу для первой строки initFirstUnitSpinnerData (the val spinnerFirstUnit one), нажмите Debug App кнопку рядом с Run единицей, и она остановится, когда достигнет той точки останова, которую вы добавили.

Затем вы можете двигаться шаг за шагом, просматривая значения stuff и проверяя, правильно ли это выглядит и как выполняется код. Это очень полезная вещь для изучения, и она избавит вас от многих головных болей!


В любом случае, я предполагаю, что ваша проблема в том, что вы вызываете initFirstUnitSpinnerData изнутри onCreateView — последнее вызывается, Fragment когда ему нужно, чтобы его вид макета раздувался, что вы и делаете, а затем возвращаете его в Fragment .

Итак, внутри initFirstUnitSpinnerData , когда вы ссылаетесь view (то есть на Фрагмент view , которого у него еще нет, потому onCreateView что он еще не вернул его), вы получаете нулевое значение. Таким spinnerFirstUnit образом, в конечном итоге получается значение null, и когда вы проверяете это значение null, он пропускает настройку адаптера.

Переопределите onViewCreated (который Fragment вызывает, когда у него есть вид макета) и вызовите вашу функцию оттуда, тогда она сможет получить доступ view — посмотрите, поможет ли это!