0

On a configuration change I do this in my FragmentActivity onSaveInstanceState:

    getSupportFragmentManager().putFragment(outState,"fred",fred);

where fred is my setRetainInstance(true) fragment.

Then in my FragmentActivity onRestoreInstanceState I do this:

    fred = getSupportFragmentManager().getFragment(inState,"fred");

as per advice in this question:When to use FragmentManager::putFragment and getFragment

where fred is defined globally like this :

 android.support.v4.app.Fragment fred=null;

I want to call a method in fred from a different method in my FragmentActivity (i.e. not from onRestoreInstanceState), which I do like this:

    ((fred) fred).somemethod(); 

which works fine before the orientation change. However, after the orientation change I encounter classCastExceptions which mention other fragments within my FragmentActivity (harry, bert etc) . The reason for these errors is probably that the Fragment Manager has been used to attach/detach the harry and bert fragments AFTER onRestoreInstanceState.

I have confirmed that my fragment fred is actually retained (I write out debug log messages from it). I am fairly certain that my problem is that I simply need to make some Fragment Manager call like this:

fred fragment = (fred) getSupportFragmentManager().findFragmentByTag("fred");

immediately prior to calling the method in fred. However, whatever I try simply returns null.

I have been working on this for a long time now and any suggestions or possible lines of enquiry would be very welcome.

Update: I did not implement the accepted solution exactly, but it made me realise that I had to instantiate fred even though it is a retained fragment. i.e. what I actually did to solve this was to perform my method call like this:

    fred fragment = (fred) getSupportFragmentManager().findFragmentByTag("fred");
    if (fragment==null){
       fragment = new fred();               //this is what I had been missing
    }

    ((fred) fred).somemethod(); 
Community
  • 1
  • 1
IanB
  • 3,489
  • 1
  • 20
  • 24

1 Answers1

1

You can do something like this:

android.support.v4.app.Fragment fred = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    FragmentManager fm = getFragmentManager();
    fred = (TaskFragment) fm.findFragmentByTag("fredFrag");

    // if fred is null it means it is first time created activity
    // so we add fragment to activity
    // else fragment was added to activity and is 
    // retained across a configuration change.
    if (fred == null) {
        fred = new Fragment();
        fm.beginTransaction().add(mTaskFragment, "fredFrag").commit();
    }
}
Koso
  • 3,200
  • 2
  • 20
  • 22
  • It did not occur to me that I would have to instantiate fred again (= new) for a retained fragment. A schoolboy error on my part - thank you very much ! – IanB Jul 15 '13 at 23:53