I followed this guide (How to run a certain activity in Android Studio?) to launch another activity aside from my main.
I have a GetUser.xml and ShowUser.xml layouts.
In GetUser.xml, user can enter their name and age.
I have a user class with constructor that takes in name and age inside GetUser.kt. I initialize User object with the values : name, age I got from the input fields in GetUser.
Now when I run the other activity ShowUser, I wish to access this object so I can get the values and display it in ShowUser.xml
My question is how do I access this object from the GetUser.kt and use it in ShowUser.kt ?
As far as I understand, you are looking for extra.
When starting one Activity from another, you can pass data via extra.
Let's say you have a class Person with String name and int age.
There are 2 simple ways to to this.
1. Send data separately
Because Person is a simple class that consists of 2 member fields, we can pass each data separately and combine into Person in started Activity.
We need Intent to do this.
val p = Person(name, age) // Person data
val intent = Intent(this, NewActivity::class.java)
intent.putExtra('name', p.name)
intent.putExtra('age', p.age)
startActivity(intent)
On started NewActivity's onCreate(), you can receive this data and make an object out of it.
val name = intent.getStringExtra('name')
val age = intent.getIntExtra('age')
val combinedPersonData = Person(name, age)
2. Send whole instance
If the class you are trying to send is too big to use method 1, you can try sending it as itself.
To do this, you need to implement Serializable or Parcelable to your class.
class Person(val name: String, val age: Int): Serializable { ... }
Make sure all of the members in the class are also Serializable or are primitive types.
With this, you can send the person object as serializable object.
val p = Person(name, age) // Person data
val intent = Intent(this, NewActivity::class.java)
intent.putExtra('person', p)
startActivity(intent)
In the receiver's onCreate(),
val p = intent.getSerializableExtra('person') as Person
will receive the while Person data.
Related
So for one of my personal projects I want to pass an arraylist of ZipEntry objects from one activity to another but I am unable to do so. I have tried the following things:
Creating Bundle() and passing that bundle using putExtra()
Passing ArrayList directly using putExta()
Creating bundle & passing it using putExtra():
Implementation:
// Add data to intent and launch install activity
val newActIntent = Intent(this, InstallActivity::class.java)
val data = Bundle()
data.putSerializable("x", languageListAdapter.selectedItems)
newActIntent.putExtra("z", data)
this.startActivity(newActIntent)
Error:
java.lang.IllegalArgumentException: Parcel: unknown type for value split_config.en.apk
Passing ArrayList<> directly using putExtra()
Implementation:
val newActIntent = Intent(this, InstallActivity::class.java)
newActIntent.putExtra("x", languageListAdapter.selectedItems)
this.startActivity(newActIntent)
Error:
java.lang.IllegalArgumentException: Parcel: unknown type for value split_config.en.apk
Note: ZipEntry object is java.util.zip.ZipEntry
In order to send an ArrayList<ZipEntry> from one Activity to another you need to make sure that your ZipEntry object is serializable, you can do it by implementing Serializable interface.
You can also use Parcelable as an alternative of Serializable.
If you use Serializable you use getSerializableExtra and if it's Parcelable you use getParcelableArrayListExtra
#Parcelize
data class ZipEntry : Parcelable
Fixed this issue thanks to the comment from #wambada
Implementation:
Created a singleton object to store the ArrayLists
object ZipEntrySingleton {
var aList: ArrayList<ZipEntry>? = null
var lList: ArrayList<ZipEntry>? = null
}
Created the singleton object in activity 1 and passed the data to it.
// Add data to intent and launch install activity
val newActIntent = Intent(this, InstallActivity::class.java)
val x = ZipEntrySingleton
x.aList = xListAdapter.selectedItems
x.lList = yListAdapter.selectedItems
this.startActivity(newActIntent)
Retrieved the data in the new activity by using:
ZipEntrySingleton.aList
I have 2 activities. And I need pass a lot of variables from one activity to another activity:
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra(ACCOUNT1, accoun1)
intent.putExtra(ACCOUNT2, accoun2)
intent.putExtra(ACCOUNT3, accoun3)
intent.putExtra(ACCOUNT4, accoun4)
intent.putExtra(ACCOUNT5, accoun5)
intent.putExtra(ACCOUNT6, accoun6)
intent.putExtra(ACCOUNT7, accoun7)
intent.putExtra(ACCOUNT8, accoun8)
intent.putExtra(ACCOUNT9, accoun9)
and so on. How can I make this transfer easier? Maybe is some other ways to pass multiply values from one activity to another activity?
I recently had a similar case.
How I solved:
I created an entity that kept all the information for me, that way, I just passed an object between activities, but I had everything I needed inside that object.
Hope this can help.
There is a bundleOf function in the Jetpack core-ktx library that works like mapOf.
val intent = Intent(this, SecondActivity::class.java)
val extras = bundleOf(
ACCOUNT1 to accoun1,
ACCOUNT2 to accoun2,
ACCOUNT3 to accoun3,
// etc.
)
intent.putExtras(extras)
But that doesn't save much code compared to just using apply unless you use the same bundle of extras in multiple places in your code:
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra(ACCOUNT1, accoun1)
putExtra(ACCOUNT2, accoun2)
putExtra(ACCOUNT3, accoun3)
//...
}
You could make a parcelable data class that stores all your values and pass that instead. See instructions here for creating the class easily: https://developer.android.com/kotlin/parcelize
#Parcelize
data class AccountInfo(
val account1: String,
val account2: String,
val account3: String,
//...
): Parcelable
Then you can put this into your bundles, and you don't have to create a bunch of the same kinds of variables in both activities, because all the variables are inside one class.
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra(ACCOUNT_INFO, myAccountInfoInstance)
}
if all of your variables has the same type you can add all to list and pass the list to second activity/fragment.
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.
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).
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")
}
I'm trying to pass data from activity A to activity B through intent in Kotlin.
The problem is I have a videos: MutableList<Video> and the intent.putParcelableArrayListExtra("VIDEOS", videos) only accepts ArrayList<out Parcelable> as arguments.
Questions
*. How do I send a mutableList data from activity A to activity B?
*. Or Do I have to convert it to ArrayList<Video> ?
PS: Videoimplements Parcelable
Converting it to an ArrayList (or storing it as one in the first place?) is the easy solution if you want to stick to passing it through an Intent. There's an ArrayList constructor that takes a collection as its parameter:
intent.putParcelableArrayListExtra("VIDEOS", ArrayList(videos))
For those asking how the Parcelable class is created, this is the solution I came up with in Kotlin
The Parcelable Class:
#Parcelize
data class ExampleModel(
var stringOne: String,
var stringTwo: String): Parcelable
Then in Activity A you can create an ArrayList and send it via intent to Activity B
private var exampleMutableList: MutableList<ExampleModel> = arrayListOf()
exampleMutableList.add(ExampleModel("hello", "world"))
intent.putExtra("example", ArrayList(exampleMutableList))
And in Activity B we can receive our ArrayList:
exampleMutableList = intent.getParcelableArrayListExtra<ExampleModel>("example") as ArrayList<ExampleModel>
All the best!
Hello this is my first app with kotlin i am trying to make annual rate calculation app the problem is i have 4 activities every activity own button and edit's texts
i wan't when The User click the button, the program get the numbers from Edit's texts and only make the calculation and save it somewhere and same work for the activity 2 and 3.
but when he click the last button of the last activity i want to call all the results and show it in ViewText
The Question is:How to save data Every time somewhere and call when i need it?
First Activity
class st {
var int_P: Double? = null
var ctl_P: Double? = null
public constructor(int_P: Any, ctl_P: Any) {
this.int_P = int_P.toString().toDouble() //Physique
this.ctl_P = ctl_P.toString().toDouble()
public fun GetMP(): Double {
return (this.int_P!! + (this.ctl_P!! * 2)) / 3
}
}
Btn_Next1.setOnClickListener ({
var int_P = java.lang.Double.parseDouble(edit_IP.text.toString()) //Physique
var ctl_P = java.lang.Double.parseDouble(edit_CP.text.toString())
var ss = st(int_P,ctl_P)
val ic = Intent(this, Sec_Act::class.java)
startActivity(ic)
})
(Secend and Third Activity Same)
Activity 4
btn1.setOnClickListener ({
var act1 = MainActivity.st().GetMC()
Textv.text = act1.toString()
})
With this method i got problem (no value passed for parameter int_P , ctl_P)
There are many different ways to send information back to an Activity:
onActivityResult(),
having a singleton class,
use Shared Preferences,
headless fragments,
sqlite database,
store the information in a file.
Intents
receivers
You need to determine which will be the best solution for you. Whether it's kotlin or java, the methodology will be the same.