16

I have an activity where I dynamically replace fragments:

private void goToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}

Now, I want to access the views inside the fragment so I can put data (that I have stored in my activity) into them, immediately after calling goToFragment.

The problem is, the fragment's onCreateView isn't called before the fragment is rendered completely, at least to my understanding.

I know overriding the onAttach(Activity activity) in the fragment is one way to go about it, but then I have to cast it specifically to my activity - and I just want to avoid that because I consider it bad practice for the fragment to be dependent on a specific activity.

As far as I can see, Fragment doesn't have any listeners (as a subject) implemented.

So I figure I have to make my own listener (Using the Observer Pattern to make the fragment a subject and the activity an observer), and then calling it whenever the onCreateView or onAttach is done, and then finally calling back to the fragment with the data that needs to be set. However, I need to do this for several fragments so I would have to make a listener for each fragment, which I again think is bad.

Is there any better/easier way to do this?

Aske B.
  • 6,419
  • 8
  • 35
  • 62

3 Answers3

37

FragmentTransaction isn't applied instantly after calling commit(). You may force update manually:

...
mFragmentManager.executePendingTransactions();

AFAIK event callbacks' purpose is custom communication with Fragment beyond it's usual lifecycle.

Andrey Ermakov
  • 3,298
  • 1
  • 25
  • 46
  • This is useful if you are passing data to fragments. If the fragments are only being used once, use fragment.setArguments(Bundle args) but if you are going to re-use the fragments then it errors so executePendingTransactions() comes in handy so you can call methods/setters on the fragment straight away. Doesn't seem too elegant though. – Sheamus O'Halloran Apr 05 '13 at 09:09
4

The correct way to do it would be to define an interface for Activity classes wishing to display your Fragment should implement. That way, on onAttach you don't cast to a specific Activity but to your interface.

See for instance: http://developer.android.com/guide/topics/fundamentals/fragments.html#EventCallbacks

K-ballo
  • 80,396
  • 20
  • 159
  • 169
  • That's at least a better solution. Even though it doesn't seem perfect, it still seems like a decent way to go. Thank you for the suggestion. EDIT: According to the link you posted (which is the official guides), it seems to be the recommended way. – Aske B. Jun 02 '12 at 18:12
  • @Aske B.: It sure beats trying to tinker with a `Fragment`'s internals – K-ballo Jun 02 '12 at 18:13
  • I get this is the way to communicate from fragment to activity but I think OPs intentions were from activity to fragment. Can this method be applied for the latter case? – amcc Nov 11 '13 at 01:00
2

You should use onActivityCreated to set the values.

Set references in onCreateView and then set values to them in onActivityCreated.

Barak
  • 16,318
  • 9
  • 52
  • 84