Search code examples
androidandroid-studiokotlintextviewpopup

How can I update textview with a data coming from within a pop-up edittext field?


First of all, I'm really a beginner in Kotlin and Android programming, so please excuse me if my question is not very smart.

I'm trying to build an app to keep track of my resources in a board game called Terraforming Mars: Ares Expedition. In the game, each player has 3 types of collectable resources; MC (Money), heat, and plants. To increase stock and income, I've used these colorful buttons to make it similar to the physical game cubes. However, when it comes to spending, I implemented spend buttons for each resource, and a pop-up window appears when it's clicked. I've followed a youtube video to implement the pop-up, and the new class that binds to it.

The problem is, I am unable to update the amount in my main table (stock part of the MC). Here is my pop-up class:

package com.example.aresboard

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import com.example.aresboard.databinding.ActivityMainBinding
import com.example.aresboard.databinding.SpendPopupBinding
import java.lang.Integer.parseInt

class SpendDialog : DialogFragment() {

    private lateinit var binding: SpendPopupBinding
    private lateinit var actBinding: ActivityMainBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = SpendPopupBinding.inflate(layoutInflater)
        actBinding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root

        binding.spendButton.setOnClickListener {
            var amount = parseInt(binding.howMuch.text.toString())
            var mainObject = MainActivity()
            mainObject.spendMcAmount(amount, actBinding)
            Toast.makeText(context, "You spent $amount", Toast.LENGTH_LONG).show()
            dismiss()
        }
        return view
    }
}

And here is the function "spendMcAmount(amount, actBinding)" I'm trying to run in my MainActivity class.

fun spendMcAmount(amount: Int, binding: ActivityMainBinding) {
    mcStock = mcStock-amount
    binding.mcStockTv.setText("" + mcStock)
}

I have very similar functions to this to increase the MC stock, running when the +1, +5, or +10 buttons are clicked in the MC line. And they work just fine. The only difference is, there is no pop-up windows involved with these buttons, so they are running in the MainActivity class. Here is the function that increases the MC by one:

fun mcOne(view: View) {
    mcStock++
    binding.mcStockTv.setText("" + mcStock)
}

I've also tried to set mcStockTextView.text which is in my MainActivity layout, directly from the SpendDialog class, but no luck there either. When I printed the value of mcStockTextView.text, it looks correct, but the display won't show the updated value. Hence, I tried what's in this question, which is creating an object of MainActivity class, and trying to call a function in that class. Still no luck.

Here is a look at my layouts:

MainActivity Layout

SpendDialog Layout


Solution

  • you dont need ActivityMainBinding in the DialogFragment

    create an interface

    interface SpendListener {
    
        fun onSpend(amount: Int)
    
    }
    

    in the DialogFragment declare SpendListener

    private lateinit var spendListener: SpendListener
    

    public method to initialize the interface

    fun setupListener(spendListener: SpendListener) {
        this.spendListener = spendListener
    }
    

    now before closing your dialog use the interface to send data to the activity

    spendListener.onSpend(10)
    

    and in your activity where you're opening the popup, setup a listener to update the UI, after the

    dialog.show(this, "TAG")
    dialog.setupListener(object: SpendListener {
        override fun onSpend(amount: Int) {
            yourTextView.text = amount.toString()
        }
    })