Robby Smet
Robby Smet

Reputation: 4661

Pass list of complex objects from activity to fragment

I have a MainActivity with a SearchFragment and a SearchResultFragment.

When the user presses the searchbutton I do a callback from the SearchFragment to the MainActivity with the SearchParameters as parameters.

On the MainActivity I than show a LoadFragment and load the results.
When I receive the results I want to pass the list of result objects to the SearchResultFragment.

What is the best way to do this?

I know you normally do it like this if it was just one result:

public static SearchResultFragment newInstance(SearchResult result) {
    SearchResultFragment f = new SearchResultFragment();
    Bundle args = new Bundle();
    args.putInt("result", result);  // Make result parceable
    f.setArguments(args);
    return f;
} 

But how do I do this with a list of objects ?

Another solution I can think of is to get a reference to the MainActivity in the onAttach method of the fragment and then call a method getResults() on the MainActivity.

What would be the best way ?

Upvotes: 3

Views: 5657

Answers (2)

desseim
desseim

Reputation: 8248

Note: my answer assumes you're trying to pass an aggregation of data to a fragment once. If you're trying to update regularly an existing fragment with new information (new results) then maybe better have a dedicated method in the Fragment to both save the results as arguments and update the UI.

Both approaches may be acceptable, especially depending on the scope you want to give to your search results, but I would favor passing the results as a "static" parameter (meaning not fetched dynamically from the Activity) mainly for the following reasons:

  • Fragments are intended as reusable pieces of UI, meaning the Android framework allows you to integrate the same Fragment in another Activity ; in this case it is easier to integrate (more flexible) than if the attached Activity has to implement a given getter, and the Fragment could actually be constructed by another entity (e.g. a "result fetcher) and attached to the Activity without it knowing about the results (eases potential refactoring)
  • Fragment arguments are retained, meaning that the same Fragment initialization code (which fetches the results from the arguments) will also handle Fragment automatic reinstantiation after an activity restart (e.g. screen rotation) for example ; otherwise you would additionally have to handle the save and restoration of the results entity yourself

On the other hand, putting the results in a Bundle as Fragment parameter will be slightly slower since after receiving new results you create an additional structure (the Bundle) which you then parcel (serialize) and unparcel (deserialize). It will be faster upon Activity restart though since you don't have to parcel it in this case (it has already been done). I just mention it for the sake of completeness though since, unless your results are very big (which is a valid use case but maybe more suited for paged loading then ?), you won't notice and anyway shouldn't care.

To pass several results to a Fragment (assuming a single result is an int):

final Bundle args = new Bundle();
args.putIntArray(SearchResultFragment.ARG_NAME_RESULTS, results);  // results being an int[]
fragment.setArguments(args);

Just use Bundle#putIntegerArrayList(String, ArrayList<Integer>) instead if results is of type ArrayList<Integer>.

Upvotes: 4

Xaver Kapeller
Xaver Kapeller

Reputation: 49817

In most cases you can avoid the need to pass complex objects but if you cannot, then just use getters and setters. Try something like this:

public static SearchResultFragment newInstance(SearchResult result) {
    SearchResultFragment f = new SearchResultFragment();
    f.setResult(result);        
    return f;
}

BUT try to avoid this, passing the data with a Bundle is a much better solution. Use Parcelable wherever you can.

Upvotes: 6

Related Questions