Search code examples
android-fragmentskotlinandroid-spinner

Kotlin - Trying to populate spinner from Fragment using findViewById(), but context: this is throwing an error


Obligatory preface: I'm quite new to Kotlin and Android Studio. As the title states, I'm trying to populate a spinner in Android Studio from within a fragment. First, I had an issue with findViewById(R.id.spinner) but I believe I've resolved it by prefixing it with root..

Currently, the only error being thrown is the context: this line. Ultimately, I'd like to use this spinner to allow the user to filter by different NY boroughs (hence, boroughs_array. Here's my current code within the FilterFragment -- my attempt to populate the spinner begins below return root.

override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?


): View? {
    filtersViewModel =
            ViewModelProviders.of(this).get(FiltersViewModel::class.java)
    val root = inflater.inflate(R.layout.fragment_filters, container, false)
    return root

    val spinner: Spinner = root.findViewById(R.id.spinner)
    // Create an ArrayAdapter using the string array and a default spinner layout
    ArrayAdapter.createFromResource(
        this,
        R.array.boroughs_array,
        android.R.layout.simple_spinner_item
    ).also { adapter ->
        // Specify the layout to use when the list of choices appears
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        // Apply the adapter to the spinner
        spinner.adapter = adapter
    }

My current assumption is that this is not the right context, as I'm within a fragment. On the off-chance that this is correct, I'm not really sure how to handle this. If you can shine any sort of light on the issue, I will be eternally grateful.


Solution

  • You need to use use context!! instead of this. this refers to the current Fragment, which is not a Context. The current Fragment has a reference to the Context though, accessed via this.getContext(), or context for short.

    The reason you need context!! is because getContext() is nullable (it may return null). It's safe in this case to 'force unwrap' (!!) because context will never be null inside onCreateView().

    Another issue I've spotted, is you're returning from the onCreateView() function before you've set up the spinner.

    Try this instead:

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    
    
    ): View? {
        filtersViewModel = ViewModelProviders.of(this).get(FiltersViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_filters, container, false)
    
        val spinner: Spinner = root.findViewById(R.id.spinner)
        // Create an ArrayAdapter using the string array and a default spinner layout
        ArrayAdapter.createFromResource(
            context!!,
            R.array.boroughs_array,
            android.R.layout.simple_spinner_item
        ).also { adapter ->
            // Specify the layout to use when the list of choices appears
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            // Apply the adapter to the spinner
            spinner.adapter = adapter
    
        return root
    }
    

    Also, just for further clarification - you've probably seen some examples where this is passed in for context. This is often done inside of an Activity, since Activity does extend Context.