Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for updating arguments of a fragment?

I know about the "newInstance"-Pattern (Best practice for instantiating a new Android Fragment). But how do I update these arguments of a fragment for example if another fragment changes data?

I know about callback-methods between Fragments/Activitys, but these callbacks won't update the arguments?!

For example: on creation of the fragment I pass an URI to the it with the bundle. Then another fragment changes this URI via changeUri(Uri uri) method callback on the first fragment. If then the fragment gets recreated (for example due to screen rotation) it will use the first URI from the arguments bundle instead of the later updated uri, correct?

What is the best practice to solve this? Do I have to manually store it in the savedInstanceState and on usage decide whether to use the instanceState or arguments-bundle?

I'm looking for a standard way of handling the arguments of my fragments, so I think I'm going with such an approach (pseudo-code):

private Uri arg1;

public static Fragment newInstance(Uri arg1) {
  create bundle
  create fragment instance
  set bundle to fragment
  return fragment
}

private void onCreate(Bundle savedInstance) {
  if(savedInstance != null) {
    arg1 = savedInstance.uri
  }
}

private Uri getUri() {
  if(arg1 == null) {
    arg1 = getArguments.uri
  }
  if(arg1 == null) {
    arg1 = defaultValue
  }
}

So I have a simply unified way to access my argument. And don't have to use the if-else-hassle, every time I need that argument.

What do you think about it?

like image 275
Maniac Avatar asked Aug 15 '13 20:08

Maniac


People also ask

What is the recommended way to pass arguments to a fragment?

To pass info to a fragment , you setArguments when you create it, and you can retrieve this argument later on the method onCreate or onCreateView of your fragment. Then inside the fragment on the method onCreate or onCreateView you can retrieve the arguments like this: Bundle args = getArguments(); int index = args.

Why is it recommended to use only the default constructor to create a fragment?

Traditionally, a Fragment instance could only be instantiated using its default empty constructor. This is because the system would need to reinitialize it under certain circumstances like configuration changes and the app's process recreation.


4 Answers

You can't change arguments once its set and Fragment is added to Activity, I used a similar approach you defined yourself.

First, I checked the Bundle passed to onCreate(), if its not null I use it, but if its null then I use arguments. And I save whatever is the newest data in onSaveInstanceState().

For more details: Is it possible to pass arguments to a fragment after it's been added to an activity?

like image 71
M-WaJeEh Avatar answered Oct 08 '22 06:10

M-WaJeEh


I just change the value in the bundle.

Example:

synchronized (fragment.getArguments()) {
    fragment.getArguments().putInt(KEY, new Value);
}

And update content with new Argument

like image 30
Bach Avatar answered Oct 08 '22 08:10

Bach


You save state the same way you would do for Activities in the Fragment's onSaveInstanceState callback. If you have updated the URI since the last onCreate(), you would store the updated URI in the Bundle, and would receive this back in onCreate(). Saving state is exactly what this is designed for, and by changing the URI, all you've done is changed state.

like image 4
323go Avatar answered Oct 08 '22 08:10

323go


Best practice for updating arguments of a fragment: Why do we need to add arguments via a newInstance() method and why is it a best practice for fragments?

Fragments can be thought of as a modular section of an Activity. This means that when we create a Fragment we need to make it modular and independent.

Suppose you need a Fragment which needs an argument to operate. We can write it this way:

MyFragmentClass mFrag = new MyFragmentClass();
Bundle bundle = new Bundle();
bundle.putString("key", value);
mFrag.setArguments(bundle);

It also works fine and you can get arguments in the onCreate method. Here is the difference: You can also make an instance of a Fragment without arguments and add it to the FragmentManager, but your fragment needs arguments to operate. Adding the newInstance method in Fragment forces the developer to add arguments when instantiating the Fragment. That's why it is said to be a best practice.

In your problem, you can use setRetainInstance(boolean retain) which prevents your Fragment from being destroyed when the parent Activity is destroyed.

like image 1
Sayem Avatar answered Oct 08 '22 06:10

Sayem