Created
December 8, 2016 01:54
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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