Gowapo
Gowapo

Reputation: 1

Why does this error when I declared this properly?

Here’s my “problematic” code which I slaved all night trying to make it work. I tried all types of variations of ArrayAdapters. I even tried ones online.

package com.balut.testinggrounds

import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import com.balut.testinggrounds.R

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Spinner

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    // access the items of the list
    val languages = resources.getStringArray(R.array.Languages)

    // access the spinner
    val spin: Spinner = findViewById(R.id.spinner)
        if ( spin != null) {
            val adapter = ArrayAdapter(this,
                    android.R.layout.simple_spinner_item, languages)
            spin.adapter = adapter

            spin.onItemSelectedListener = object :
                    AdapterView.OnItemSelectedListener {
                override fun onItemSelected(parent: AdapterView<*>,
                                            view: View, position: Int, id: Long) {
                    Toast.makeText(this@MainActivity,
                            getString(R.string.selected_item) + " " +
                                    "" + languages[position], Toast.LENGTH_SHORT).show()
                }

                override fun onNothingSelected(parent: AdapterView<*>) {
                    // write code to perform some action
                }
            }
        }
}

Note: I typed that again and again just to make sure I didn’t make a mistake.

Upvotes: 0

Views: 43

Answers (2)

cactustictacs
cactustictacs

Reputation: 19592

resources is shorthand for getResources() and it requires a Context, which the Activity doesn't have when it's first constructed (which is when your member variables are initialised). You'll have a context by the time onCreate runs.

findViewById requires the activity to have inflated its layout, which doesn't happen until setContentView is called in onCreate. If it's run at construction time (like here) then it will fail to find R.id.spinner, and spin will be null - but you've declared it as the non-null type Spinner so that will cause a crash.

Either do like @laalto says and initialise these in something like onCreate (preferably using lateinit so they don't need to be nullable), where you have your context and layout view, or wrap them in a lazy delegate and access them in or after onCreate.

And post your error stacktraces! That way people can tell you exactly why you're getting a crash

Upvotes: 0

laalto
laalto

Reputation: 152907

Move the code to a lifecycle function such as onCreate() rather than being on the class body level.

Upvotes: 4

Related Questions