简体   繁体   中英

Cannot populate spinner with data from database?

I'm trying to populate a spinner with data using room, I'm getting no errors but my spinner isn't displaying anything. I think it might have something to do with how I'm calling initFirstUnitSpinnerData() in my onCreateView method? But I'm having no luck. I'm using kotlin.

Thanks in advance.

DAO:

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

Repository:

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

View Model:

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

Fragment:

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<*>?) {
                
            }
        }
    }
}


}

This is the kind of thing you should debug really - click on the left gutter for the first line of initFirstUnitSpinnerData (the val spinnerFirstUnit one), click the Debug App button up near the Run one, and it'll pause when it hits that breakpoint you added.

Then you can move through, step by step, looking at the values of stuff and checking if it looks right, and how the code executes. It's a super useful thing to learn and it'll save you a lot of headaches!


Anyway I'm guessing your problem is that you're calling initFirstUnitSpinnerData from inside onCreateView - the latter is called by the Fragment when it needs its layout view inflating, which you do and then return it to the Fragment .

So inside initFirstUnitSpinnerData , when you reference view (ie the Fragment's view , which it doesn't have yet, because onCreateView hasn't returned it yet) you're getting a null value. So spinnerFirstUnit ends up null, and when you null check that, it skips setting up the adapter.

Override onViewCreated (which the Fragment calls when it has its layout view) and call your function from there, it'll be able to access view then - see if that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM