How do you pass LiveData with intent to another Activity?
I'm trying to pass the LiveData object into a new Activity that uses ViewPager 2 to display one object at a time.
Here is Live data in the ViewModel
private LiveData<List<WrestlersEntity>> mWrestlersList;
public LiveData<List<WrestlersEntity>> getWrestlersList() {
return mWrestlersList;
}
Fragment passing live data.
adapter.setOnItemClickListener(wrestler -> {
Bundle bundle = new Bundle();
bundle.putSerializable("Value", (Serializable)mViewModel.getWrestlersList());
Intent addEditIntent = new Intent(getActivity(), AddEditWrestlerActivity.class);
addEditIntent.putExtras(bundle);
startActivityForResult(addEditIntent);
Pager Activity
Intent intent = this.getIntent();
Bundle bundle = intent.getExtras();
List<WrestlersEntity> wrestler (List<WrestlersEntity>)bundle.getSerializable("Value");
I get the following error.
java.lang.ClassCastException: androidx.room.RoomTrackingLiveData cannot be cast to java.io.Serializable
If you can't cast live data as Serializable what are my other options to pass a LiveData> to a new activity.
here is a link to the git if you want to look at the full code.
https://github.com/Shawn-Nichol/Wrestlers
Your getWrestlersList() method returns a LiveData wrapping your List<WrestlersEntity>. What you want to pass to your Bundle is the List<WrestlersEntity> directly, but wrapped in a Serialized implementation of List. That's why the code below wraps the value of your LiveData in an ArrayList.
So, you can do this instead:
bundle.putSerializable("Value", new ArrayList<>(mViewModel.getWrestlersList().getValue()));
And this to read it back from the Bundle:
List<WrestlersEntity> wrestlers = (List<WrestlersEntity>)bundle.getSerializable("Value");
Related
Whats the difference between pass the variables like this:
Intent intent = new Intent(mCtx, DetailsActivity.class);
intent.putExtra("pId", id);
intent.putExtra("pType", type);
mCtx.startActivity(intent);
and using the keyword Bundle?
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
// Now let's Pass data using Bundle
Bundle bundle = new Bundle();
bundle.putString("pId", id);
bundle.putString("pType", type;
intent.putExtras(bundle);
startActivity(intent);
Im new to Android development and I am curious to which method is better or stadard when doing android development?
Intent
public Intent putExtra(String name, String value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putString(name, value);
return this;
}
Bundle
public void putString(String key, String value) {
unparcel();
mMap.put(key, value);
}
putExtras does not put your bundle inside Intent. Instead, it copies it over to the current intent bundle.
public Intent putExtras(Bundle extras) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putAll(extras);
return this;
}
The first method is recommended. All samples are using the first putExtra (key, value) methods.
In most scenarios you should know what you are passing to the next activity, so putExtra ( key, value ) makes sense because you know what the key is.
The only scenario I can think of to use the second method is a transient activity which receives bundle from previous activity and need to pass all information to next activity. The transient activity does not need to know what is being passed and just pass everything it received to the next activity.
BTW, if you create your own Bundle, put the key values in and then call putExtra ( bundle), there is extra cost for the temporary bundle so it is less efficient.
Whats the difference between pass the variables like this and using the keyword Bundle?
One puts the keys directly and one puts them in a Bundle first. The end result is the same.
Im new to Android development and I am curious to which method is better or stadard when doing android development?
The first is "better" or more "standard" simply because it eliminates the need to create the bundle yourself first - it's a redundant step. You'd really only ever need to use that method if your code already had some logic that maintained a Bundle of data that you wanted to pass along in an Intent as key / value pairs.
I have an Adapter which uses some custom object list. I wanted to pass the clicked object's to the other activity. So I made the object class implement Parcelable.
To send the data from the adapter
view.findViewById(R.id.play_btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), YouTubePlayerActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("data", movie));
intent.putExtras(bundle);
mContext.startActivity(intent);
To receive the data in the destination activity
Bundle b = getIntent().getExtras();
ArrayList<Video> videos = b.getParcelable("data");
But when I run it, it would pass nothing.
I tried passing other simpler values like strings and integer and they were too not passed.
Then I had to achieve the task by creating interface. And it worked. But I still don't understand this unexpected behavior when starting activity from adapters. Can you please answer the reason behind this unexpected behavior?
I have two activities. And I passed the argument to the target activity by intent:
Bundle bundle = new Bundle();
bundle.putString("ImagePath", path);
Intent intent = new Intent(getActivity(), DetailActivity.class);
intent.putExtra("paths", bundle);
startActivity(intent);
The target activity DetailActivity has a fragment, and I want to get the argument ImagePath in it. Now I have two method:
I get the argument in the DetailActivity by getIntent() and then pass it to the fragment using setArgmunets()
I get the argument in the target fragment using getActivity().getIntent() directly.
I like the method 2 and use it now because the clean code. But the Android Studio tell me the message Method invocation 'getIntent' may produce 'java.lang.NullPointerException' in getIntent().
So should I abandon the method 2?
Update: Final, I used the method 1, because of this answer :
From the Fragment documentation:
Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
You can check for extras..
Intent intent = getActivity().getIntent();
if(intent.hasExtra("paths")){
// get the data
}else{
// Do something else
}
Use Below Code :
Bundle bundle = new Bundle();
bundle.putString(Constants.BUNDLE_DATA, "From Activity");
Fragment fragment = new Fragment();
fragment.setArguments(bundle);
and in Fragment onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString(Constants.BUNDLE_DATA);
return inflater.inflate(R.layout.fragment, container, false);
}
If you want to send large data ,then create a model and make that model implements Serializable .
No, it's not about the intent. It's because in some point of the time(e.g. fragment has been detached from the activity) getActivity() method can return null. So, correct call will be the next:
if(getActivity != null) getActivity().getIntent()
getActivity() on Fragment may produce null.
So you need to use either any interface for communication between activity and fragment or use bundle by passing in setArgument() in instance of fragment.
I have a reference to an anonymous class object that I want to pass to an activity. It is a kind of reference to a callback fn which gets called based on an action on activity i.e. click of button. But, I dont know a way to do so as activities can not be instantiated directly (done only through startActivity) and using intents will pass my object by value not by reference. So, I need tips on a good solution. I want to avoid statics.
Short Answer: No You cannot pass objects as references to activities.
Try this
CustomListing currentListing = new CustomListing();
Intent i = new Intent();
Bundle b = new Bundle();
b.putParcelable(Constants.CUSTOM_LISTING, currentListing);
i.putExtras(b);
i.setClass(this, SearchDetailsActivity.class);
startActivity(i);
Afterwards to call
Bundle b = this.getIntent().getExtras();
if (b != null)
mCurrentListing = b.getParcelable(Constants.CUSTOM_LISTING);
Here is the answer :
Create a public static method in the Activity to which you want to pass the reference of an object.
public static void openActivity(Activity activity, Class object){
YourNextActivity.object = object;
Intent intent = new Intent(activity, YourNextActivity.class);
activity.startActivity(intent);
}
Call this method from current Activity :
YourNextActivity.openActivity(this, classObject);
I have a sign-up form, and I have to pass all info filled in that form to another screen. I know how to display if there is one field, but in sign-up form there are multiple fields. so I want to know how to display all the info.
If you are launching a new activity, just create a Bundle, add your values, and pass it into the new activity by attaching it to the Intent you are using:
/*
* In your first Activity:
*/
String value = "something you want to pass along";
String anotherValue = "another something you would like to pass along";
Bundle bundle = new Bundle();
bundle.putString("value", value);
bundle.putString("another value", anotherValue);
// create your intent
intent.putExtra(bundle);
startActivity(intent);
/*
* Then in your second activity:
*/
Bundle bundle = this.getIntent().getExtras();
String value = bundle.getString("value");
String anotherValue = bundle.getString("another value");
To pass User data(multiple info) from one screen to another screen :
Create a model for user with setter and getter method.
make this class Serializable or Parcelable (Prefer) .
Create object of user class and set all data using setter method.
Pass this object from one activity to another by using putSerializable.
Person mPerson = new Person();
mPerson.setAge(25);
Intent mIntent = new Intent(Activity1.this, Activity2.class);
Bundle mBundle = new Bundle();
mBundle.putSerializable(SER_KEY,mPerson);
mIntent.putExtras(mBundle);
startActivity(mIntent);
And get this object from activity 2 in on create methode.
Person mPerson = (Person)getIntent().getSerializableExtra(SER_KEY);
and SER_KEY will be same.
for more detail please go to this link:
http://www.easyinfogeek.com/2014/01/android-tutorial-two-methods-of-passing.html
I hope it will work for you.
You can make use of bundle for passing values from one screen to other
Passing a Bundle on startActivity()?