0

How to update the text of Textview in kotlin. Set Text on-create function works but when I tried outside main fun it says unresolved ref.

How can I declare widget for reuse TextView for update the Text Value? I don't have exp with kotlin. Can somebody help me?

class MediaPickedActivity : AppCompatActivity() {

    val fullName = "Test User"
    var score = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_media_picked)

        val Tv_test = findViewById(R.id.tv_text) as TextView

        Tv_test.setText("$fullName :: $score ")

        if (score in 0..300) {
            score = 5
            setText()
        }

    }

    private fun setText() {
        // Error is here. I can't set text.
        Tv_test.setText("$fullName :: $score ")
    }

}

enter image description here

Jigar Patel
  • 1,550
  • 2
  • 13
  • 29

3 Answers3

0

You should declare your Views as class level properties, and then you can access them from anywhere within the class. A variable declared inside a function is only accessible in that function.

class MediaPickedActivity : AppCompatActivity() {
    lateinit var Tv_test: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_media_picked)

        Tv_test = findViewById(R.id.tv_text) as TextView
    }

    private fun setText() {
        Tv_test.setText("$fullName :: $score ")
    }
}

I used lateinit in this example, but see a detailed discussion about different ways to declare the property here.

zsmb13
  • 85,752
  • 11
  • 221
  • 226
0

On top of what @zsmb13 said, you can also use the Kotlin Android Extensions plugin (since you included it as one of the topics) which is super convenient for minimizing potential findViewById() bugs, excluding the use of View fields/member variables, and etc. as follows:

First apply the plugin in your local build.gradle file:

apply plugin: 'kotlin-android-extensions'

Next, import the widget properties for a certain layout in your Activity class:

import kotlinx.android.synthetic.main.<layout>.*

... and then your Activity would be as follows:

import kotlinx.android.synthetic.main.activity_media_picked.*

class MediaPickedActivity : AppCompatActivity() {

    val fullName = "Test User"
    var score = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_media_picked)

        // Simply references via the TextView's ID, and sets its text.
        tv_text.setText("$fullName :: $score ")

        if (score in 0..300) {
            score = 5
            setText()
        }

    }

    private fun setText() {
        tv_text.setText("$fullName :: $score ")
    }

}
DaveNOTDavid
  • 1,753
  • 5
  • 19
  • 37
-1

you can also using a lazy property which will initializing the property once in needed and separate initialization from your logic, for example:

class MediaPickedActivity : AppCompatActivity() {
    val Tv_test by lazy { findViewById(R.id.tv_text) as TextView }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_media_picked)

        Tv_test.setText("$fullName :: $score ")
        // ...
    }

    private fun setText() {
        Tv_test.setText("$fullName :: $score ")
    }

}

OR write an inline function with a reified type parameter T to makes the code more readable.

class MediaPickedActivity : AppCompatActivity() {
    val nonNull by find<TextView>(R.id.tv_text)
    val nullable by find<TextView?>(R.id.tv_text)
    // ...
}

inline fun <reified T : View?> Activity.find(id: Int): Lazy<T> {
   return lazy { findViewById(id) as T }
}
holi-java
  • 29,655
  • 7
  • 72
  • 83