I'm trying to do something like this:
public class MyFancyFragment<T> extends Fragment { ... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... getChildFragmentManager().beginTransaction() .add(R.id.fancy_fragment_layout_id, new T(), "whatever") .commit(); ... } ... }
And later specify to the MyFancyFragment class which inner Fragment it's supposed to be using via, e.g.
...new MyFancyFragment<FancyInnerFragmentType>()...
But of course Java won't let me create a new T because that's not how generics work.
There's a reason I'm trying to do it that way. If you do it the way you'd normally be tempted, i.e.:
public class MyFancyFragment<T> extends Fragment { ... Fragment toShow; public void setFragment(Fragment toShow) { this.toShow = toShow; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... getChildFragmentManager().beginTransaction() .add(R.id.fancy_fragment_layout_id, toShow, "whatever") .commit(); ... } ... }
You'll be fine at first, but the issue comes down to the Android Fragment architecture. If you use MyFancyFragment on a fragment backstack, android could at any time destroy the Fragment, and then go to recreate it later via its public empty constructor. When it does this, it's not going to know to call setFragment() for you. I could go the ViewPager design route and set an Adapter to generate the Fragment on demand; but I'm now actually really confused about ViewPager - if the ViewPager fragment is destroyed and recreated via backstack operations, won't it forget about its Adapter?
I also thought maybe I could take a Fragment type when I create MyFancyFragment the first time (so pass a Class instead of a Fragment to setFragment() above), create an instance using it on the fly in onCreateView(), and try to marshal that class type to my bundle in onSaveInstanceState() for later if I need to onCreateView() again: but I don't know how to store non-primitive types like that in the Bundle? I could setup a primitive<->type instance map, but then I lose compiler support to ensure somebody updates that map when they go to create a new instance; and you're screwed if that new instance you wanted to use would have been an anonymous class.
It seems like the only way to go about doing this is to declare MyFancyFragment abstract and create anonymous inner classes extending it that return the target inner fragment (similar to many common examples involving DialogFragment and its onCreateView()); but this gets really hairy if the level of nesting gets very deep :(. In my present situation I have a DialogFragment that contains an A that contains a B that contains a MyFancyFragment, and if I start requiring dynamic subclassing, I'd have to subclass each of DialogFragment, A, B, and MyFrancyFragment to make it work, for each popup I want to show (and there are several). With generics I thought I could just declare an A() and be ok, and T would trickle down; but I can't figure out how to do it or anything like it.
How are we supposed to do this?