Search code examples
androidandroid-studioclasskotlinandroid-activity

Best way to update values for views in activity from any class with Kotlin in android 4.1.1


I'm trying to update values in a TextView from an external class but not work, I'm trying with many ways y many posts but unlucky me... BTW sent the TextView like a parameter in class and works but we know that not is the best way if I have many views.

So first with a basic code:

In Main Activity XML:


<TextView
        android:id="@+id/tvHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

In code:

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

        ClaseDePrueba(this@MainActivity)
    }
}

Finally in class with my last proof

class ClaseDePrueba(ctx : Context)
{
    val view = LayoutInflater.from(ctx).inflate(R.layout.activity_main,null,false)
    view.tvHello.text = "New Value"
}

Even I try to use the Kotlin android extensions like this web site but not work for me

https://antonioleiva.com/kotlin-android-extensions/

import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*

A few hours ago I tried to implement an interface but I don't know how to reference the TextView and chance value, my code:

class MainActivity : AppCompatActivity() , ClaseDePrueba.MyInterfaceClass {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        ClaseDePrueba(this@MainActivity)

    }

    override fun updateClass() {
        TODO("Not yet implemented")
    }

And my class

class ClaseDePrueba(ctx: Context)
{

    interface MyInterfaceClass {
        fun updateClass(
        )
    }

So the question is... What is the (best) way to fix and do it work correctly?

UPDATE and one solution

well I solved created a list of objects and pass as a parameter

I don't know if is the best way but at the moment works thanks all


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

        val textViews = ArrayList<TextView>()
        textViews.add(tvHello)
        textViews.add(tvHello2)

        ClaseDePrueba(this@MainActivity, textViews)

    }
class ClaseDePrueba(ctx: Context, private val tviews: ArrayList<TextView>? = null)
{
    init {
        if (tviews != null) {
            tviews[0].text = "Init1"
            tviews[1].text = "Init2"
        }
    }

Solution

  • If you have an Activity, and it inflates a layout, it creates the objects in the XML and assigns them IDs. The XML is like a recipe, the Activity is the cook, baking a delicious view layout.

    So your Activity has some TextView objects. If you have another class, and that inflates the same XML file, it creates different objects. It's baking its own layout, and any changes you make to those View objects won't be seen in the Activity, because it has a completely different set of TextView instances (which happen to share ID values, because that's what the XML recipe says)

    So if you want to mess with those TextViews in the Activity, you have three basic options:

    • have the Activity pass them to the other class, in a collection like a list. ("Here you are, here's the stuff you need to work with")
    • make them publicly accessible in the Activity, so you can pass the Activity instance to your other class, and it can poke them directly e.g. myActivity.coolTextView1.text = "wow!"
    • make some kind of interface on the Activity, e.g. fun updateText(id: Int, text: String) which the other class can call when it needs to update something. The Activity handles the details internally, like finding the relevant TextView object and updating it

    either way, if you want to change those specific TextView instances displayed in your Activity, you need to access those instances somehow