Skip to content

Instantly share code, notes, and snippets.

@keyboardr
Created December 8, 2016 01:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keyboardr/5508c58ce6a02a7a8a0e9004efa9a0a7 to your computer and use it in GitHub Desktop.
Save keyboardr/5508c58ce6a02a7a8a0e9004efa9a0a7 to your computer and use it in GitHub Desktop.
Demonstration of why the HeadlessFragment gist can't be done as an abstract Factory class
/**
* What you'd think an abstract factory would look like. Unfortunately, this class won't compile.
*/
public abstract class HeadlessFragmentFactory<F extends Fragment & ParentedFragment<F, ? extends P>, P> {
protected abstract F newInstance();
/* There will be a compiler warning on P. When joining types, only the first type is allowed to
be a class. All others MUST be interfaces. In this situation, there is no way for the compiler
to know that P will be an interface. If P is removed, there is no longer a compile-time check
that the parent implements the necessary callback interface */
public <A extends FragmentActivity & P> F attach(A parent, String tag) {
return attach(parent.getSupportFragmentManager(), tag);
}
// Same as above
public <A extends Fragment & P> F attach(A parent, String tag) {
return attach(parent.getChildFragmentManager(), tag);
}
private F attach(FragmentManager fragmentManager, String tag) {
F frag = ((F) fragmentManager.findFragmentByTag(tag));
if (frag == null) {
frag = newInstance();
fragmentManager.beginTransaction().add(frag, tag).commitNow();
}
return frag;
}
}
/**
* Fragment that requires a parent of type P. T is a self-referential generic that also forces
* the implementation to extend Fragment
*/
public interface ParentedFragment<T extends Fragment & ParentedFragment<T, P>, P> {
//Example parent interface
interface FragmentParent {}
//Example fragment implementation
class ParentedFragmentImpl extends Fragment
implements ParentedFragment<ParentedFragmentImpl, FragmentParent> {
}
//Example factory
HeadlessFragmentFactory<ParentedFragmentImpl, FragmentParent> IMPL_FACTORY
= new HeadlessFragmentFactory<ParentedFragmentImpl, FragmentParent>() {
@Override
protected ParentedFragmentImpl newInstance() {
return new ParentedFragmentImpl();
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment