Home > Software engineering >  how to get a variable in an activity from another activity and make the main activity to use variabl
how to get a variable in an activity from another activity and make the main activity to use variabl

Time:07-10

my kotlin project has 2 activitis (main , second called : AddPlayer) main activity has a button called "Add a player" that it starts second activity . in second activity i have 2 edit text to get a number and a text from user . after press submit button in second activity , in the main activity i want add these values to my mutablelist but idk how to do it ( i think it crashed because main activity uses those variables before getting values from user) plz guide me .

my activity code :

class MainActivity : AppCompatActivity() {
private var enteredPlayerNumber = 0
 private var enteredPlayerName: String=""

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val myRecyclerView = findViewById<RecyclerView>(R.id.recyclerView)
    val myViewModel = ViewModel()
    val btnAdd = findViewById<Button>(R.id.btnAdd)



    myRecyclerView.layoutManager = LinearLayoutManager(this)

    myViewModel.getUserData()
    btnAdd.setOnClickListener {
        val myIntent = Intent(this, AddPlayerActivity::class.java)
        startActivity(myIntent)
    }




    myViewModel.myList.observe(this) {
        myRecyclerView.adapter = MyAdapter(it)
    }


}}

and my second activity :

class AddPlayerActivity : AppCompatActivity() {


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

    val numberAddPlayer = findViewById<EditText>(R.id.etNumberAdd2)
    val nameAddPlayer = findViewById<EditText>(R.id.etNameAdd2)

    val btn = findViewById<Button>(R.id.btnSubmitAdd2)



    btn.setOnClickListener {
        val myIntent=Intent(this,MainActivity::class.java)
        myIntent.putExtra("USERNAME", nameAddPlayer.text)
        myIntent.putExtra("USER_NUMBER", numberAddPlayer.text)
        startActivity(myIntent)

    }

}}

CodePudding user response:

If you want to pull data out of an Intent that was used to start an Activity, just do this in your onCreate:

intent?.run {
    val userName = getStringExtra("USERNAME")
    val userNumber = getStringExtra("USER_NUMBER")

    if (username != null && userNumber != null {
        // do whatever with that data
    }
}

You need to null-check because those values might not be present, e.g. if MainActivity was started by launching the app, not by the button being clicked in AddPlayerActivity.

Also, if you click the button and get back to MainActivity, and put the app in the background and it gets destroyed, when it's recreated onCreate will run again, see the same intent (the last one is preserved when it's recreating the state) and it'll pull the values and do the thing with them again. If that means adding something to a list, you might get duplicates

One way to avoid that is check if savedInstanceState is null - if it is, you're coming into the activity fresh, so it's ok to check the intent. If it's not null, then you're recreating some saved state from an already-open activity, so you don't want to repeat the check

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (savedInstanceState == null) {
        // do the intent stuff
    }

but that might depend on what you're doing with your activities and the task backstack - test it to make sure it's doing what you expect!


The recommended approach by the Android devs at this point is a single-activity architecture where instead of an Activity for each screen, you have just one, and use Fragments for your screens and swap them in and out instead.

A lot of the Jetpack components are designed around this idea, including the Navigation library, and ViewModels which allow the Fragments that share an Activity to also share a central store of data and react to changes.

Looks like you're already using a ViewModel, but by sharing an Activity you'd be able to have your AddPlayer fragment do something like model.addUser(name, number). The model could store that new user if you want (e.g. in a database, or SharedPreferences or whatever) and update the data it's making visible. MainFragment could observe that data and update its display as necessary

Doing things that way is a lot easier to reason about, you don't need to worry about Activity states etc (part of the reason for creating ViewModel is so a lot of that work is taken care of for you) and it's a more modern way to write Android apps. Might be worth looking into!

  • Related