-1

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)

    }

}}
  • startActivityForResult... Try this https://stackoverflow.com/questions/71082372/startactivityforresult-is-deprecated-im-trying-to-update-my-code – Gobu CSG Jul 08 '22 at 16:59

1 Answers1

0

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!

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • thank you , excuse me i have a question , i added ( intent?.run ) part into my code , it woked just for one time and each time i wanna add a player again , it is replaced the previous one , how can i solve it ? – M.hossein Karimi Jul 09 '22 at 16:06
  • @M.hosseinKarimi when the Activity is first created (so it runs `onCreate`) you're checking if the `Intent` used to start the activity has your piece of data in it. Basically, you're checking if you just came from `AddPlayerActivity`, which only sends over one piece of data. If you want to take that data and add it to some collection you're building up, you'll need a way to store that collection, load it when the Activity starts, and add any new data that's in the `Intent`. Persisting data is a big topic - here's the Android docs: https://developer.android.com/guide/topics/data/ – cactustictacs Jul 09 '22 at 19:30
  • specially tnx to you – M.hossein Karimi Jul 09 '22 at 21:34