0

after researching a lot, I wasn't able to find the real solution for my problem. The most answers are based on attaching single parcelable object to an intent and starting a new activity from it.

In my case, I use data from two different parcelable classes. I have two different RecyclerView Adapter classes that live in the same activity.

So, when the user clicks on a data set from the first (parent) Adapter class, the View shows all available (child) data sets from the second Adapter class.

I want to save the parent object data set where the user clicked first, as well the child object where the user performed a long click at last. The both objects need to be attached on a same intent and when done, a new activity should be started. The data from the both objects (parent and child) has to be passed in the new acticity.

For the sake of clearness, I'm posting only the relevant parts of the code.

This is the part of the parent adapter class where I need to save the object data to a sort of "global" intent, my code would produce only a local intent instead (that's why it's commented only).

                itemView.setOnClickListener {
                notifyItemChanged(selectedPos)
                selectedPos = adapterPosition
                notifyItemChanged(selectedPos)
                listener.onHeadItemClicked(weKopf.WENR, p1)
                // save parent parcelable object data to "global" intent 
                // val intent = Intent(context, StorageGoodsActivity::class.java)
                // intent.putExtra("weKopf", weKopf)

            }

Here is the part of the code where I want to attach the child object data to the same intent and then start the new activity.

                itemView.setOnLongClickListener{
                notifyItemChanged(selectedPos)
                selectedPos = adapterPosition
                notifyItemChanged(selectedPos)
                listener.onPositionLongClicked(wePos.lfdNr.toInt())
                /**
                 * setting-up for passing objects between activities
                 */
                val intent = Intent(context, StorageGoodsActivity::class.java)
                //intent.putExtra("weKopf", weKopf)
                intent.putExtra("wePos", wePos)
                context.startActivity(intent)
                true

What is the most elegant way to do this? My idea was to store the intent into a shared component, but this intent should live as long as the user clicks the back button to return to the old activity and chooses new parent-child constellation after that. If so, will this created item be thrown away, or it still lives in the shared component?

I'm quite new with Android Studio and Kotlin and I appreciate every help or advice. Thank you so much in advance.

BWappsAndmore
  • 491
  • 3
  • 17

2 Answers2

1

You can have as many extras as you want in an Intent, so long as each gets its own name. The only limitation is a limitation on the total size of an Intent (about 2 MB iirc).

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Thank you for your response. But how do you create the "global" intent that stores both objects and lives until the user presses the back button to return in the old activity? I have to call the Intent in the both Adapter classes and attach the data first, before I start the new Activity with it. – BWappsAndmore Sep 20 '19 at 15:03
  • 1
    You wouldn't. When the user presses the back button, you go back to the old activity. If that was still in memory, you'll go back to exactly where it was. If it was killed for resources, you should be implementing onSaveInstanceState and onRestoreInstanceState to do the loading and unloading of state. There's no place there an Intent should be used. If you're actually trying ot make the back button go to some 3rd intent instead- well don't. THat's not how Android works. But even then, you'd pass the data to the 2nd intent and have it launch the 3rd intent, not somehow save it globally – Gabe Sechan Sep 20 '19 at 15:36
  • Yes, indeed. I can start a new Activity only once and I guess I'm able to do this with only one single intent. So, how can this intent contain the data from both adapters/parcelable classes? – BWappsAndmore Sep 20 '19 at 19:39
0

The solution of this problem was sort of small work around. It was impossible to attach the data objects from both adapter classes in the same intent, because the new activity can be started from only one adapter. In this case, I passed the data object from the first (parent) adapter to a SharedPreferences object, the object was converted with Gson into his JSON representation.

itemView.setOnClickListener {
                notifyItemChanged(selectedPos)
                selectedPos = adapterPosition
                notifyItemChanged(selectedPos)
                listener.onHeadItemClicked(weKopf.WENR, p1)

                /**
                 * store object in SharedPreferences
                 */
                val sharedPreferences:SharedPreferences = context.getSharedPreferences("StoreHeadObj", MODE_PRIVATE)
                val editor : SharedPreferences.Editor = sharedPreferences.edit()
                val gson = Gson()
                val json = gson.toJson(weKopf)

                editor.putString("JSONString", json)
                editor.commit()

The second (child) object was passed on an intent and the new Activity was started.

itemView.setOnLongClickListener{
                notifyItemChanged(selectedPos)
                selectedPos = adapterPosition
                notifyItemChanged(selectedPos)
                listener.onPositionLongClicked(wePos.lfdNr.toInt())
                /**
                 * setting-up for passing objects between activities
                 */                
                val intentPos = Intent(context, StorageGoodsActivity::class.java)                
                intentPos.putExtra("wePos",wePos)
                context.startActivity(intentPos)

                true
}

In the new Activity, I'm retrieving the data from both objects. First of all, I'm converting the JSON String to a data object, after that I'm taking the data out of the Intent. So, both of the parcelable data objects are now ready to use in the new Activity.

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getContentView())

        /**
         * get data from clicked weKopf-Object using Gson, at the end clear SharedPreferences
         */
        val sharedPreferences:SharedPreferences = getSharedPreferences("StoreHeadObj", Context.MODE_PRIVATE)
        val gson = Gson()
        val json:String = sharedPreferences.getString("JSONString", "")
        val weKopf:WeKopf = gson.fromJson(json, WeKopf::class.java)
        /**
         * get data from long-clicked wePos-Object using Intent
         */
        val extras = getIntent().getExtras()
        val wePos = extras.getParcelable<WePos>("wePos")
}
BWappsAndmore
  • 491
  • 3
  • 17