Square has a library that most people don’t know about. It’s called . Not a very descriptive name, and there isn’t all that much info about it on the page either. coordinators Github Simple lifecycle for your MVWhatever on . No kidding. Android And some example code: class ExampleCoordinator extends Coordinator { @Override public void attach(View view) {// Attach listeners, load state, whatever.} @Override public void detach(View view) {// Unbind listeners, save state, go nuts.}} And that you can install a to any : Coordinator View // Bind a Coordinator to a View.Coordinators.bind(view, coordinatorProvider); It really doesn’t say anything about what it is, what it does, and how it should be used, right? Well, in order to understand this problem, we must walk through the evolution of custom viewgroups, because this is, apparently, the next step. The evolution of displaying screens on Android (Feel free to skip forward to the good stuff if the Activity/Fragment stuff bores you!) Activity Everybody knows Activities. They supposedly represent a single screen in the app, and is technically an “entry point” according to specific intent filters you can define. In order to start a new Activity, you use an , like . Intent activity.startActivity(activity, OtherActivity.class) They also cannot be nested. Well okay, that’s not entirely true, there’s and , but they’re quite deprecated since API Level 11. We may as well pretend they don’t exist. LocalActivityManager ActivityGroup Activities display view groups with . People generally assumed that it only shows one particular type of viewgroup specified with its layout id ( ), and then if you ever needed a different screen, you’d just make a new Activity instead. setContentView() R.layout.activity_main Then once you had to put two different screens on the same “page”, all hell broke loose. Fragments Fragment/Activity lifecycle from by Steve Pomeroy https://github.com/xxv/android-lifecycle Fragments are, well, “fragments” of a screen. They display a custom viewgroup, and are managed by the inside the Activity. The is associated with a , which is associated with the “host Activity”. technically FragmentManager Fragment FragmentController They were designed primarily so that you can create “sub-screens” that function like “sub-activities”, inheriting all important lifecycle callbacks such as , , , and even more importantly . onCreate() onActivityResult() onPermissionResult() onSaveInstanceState(Bundle bundle); They also add their own set of lifecycle callbacks, such as , , , , and . onAttach() onCreateView() onActivityCreated() onDestroyView() onDetach() You can create Fragments with . getSupportFragmentManager().beginTransaction().add(R.id.container, new MyFragment()).commit(); Most of the time though, you just need to access the Activity you’re bound to, (typically done with ), and the pairs and . somehow onAttach() onCreateView() onDestroyView() That, and now with all the additional complexity, you can nest a Fragment inside a Fragment, by — which can sometimes cause confusion in whether you need or . using the Fragment’s [getChildFragmentManager()](http://stackoverflow.com/a/13391359/2413303) getFragmentManager() getChildFragmentManager() One may ask, do we really NEED all these lifecycle callbacks in our “subview” inside the Activity? We may also ask, if we can have “subviews” in our Activity, then why create multiple Activities in the first place? Custom Viewgroups You know what Activities and Fragments have in common? They display that are already inherently nestable ( and ), they’re all declared in XML, and they also have some nice callbacks. Viewgroups ViewGroup View Makes you wonder why we were trying to use them to show different screens in the first place, when you can just swap out views and get the same result. We can extend the viewgroup of our choice ( , , , , etc.) and use the new custom viewgroup of our choice as whatever we’re inheriting from. DrawerLayout RelativeLayout FrameLayout LinearLayout Because we use layout inflation using the to inflate the custom viewgroup, the views we bind in or are always guaranteed to exist in . R.layout.custom_viewgroup @OnClick @BindView onFinishInflate() So in essence, we have something akin to , and callbacks out of the box. onViewCreated() onStart() onStop() Instead of , we can easily just , or . getSupportFragmentManager().beginTransaction().blah().commit() inflate addView removeView But even though we’ve made a subscreen that’s no longer directly bound to a messy blob of unnecessary callbacks, orchestrated by the arcane — there’s one thing that might still bother us. FragmentManagerImpl The custom viewgroup is created via inflation, and it’s not a POJO. It has 4 constructors, and needs to extend an Android-specific class to work. Coordinators In order to detach ourselves from the confines of a Custom Viewgroup, we can move all “view controller” logic outside of the viewgroup itself, and attach it as a tag. This is how it works: So what happens is that you can create a Coordinator, which can be pretty much any POJO class, and can be attached to any custom viewgroup without having to extend it. And with Coordinators, you receive a callback for and . in place of the original viewgroup’s and callbacks. attach(View) detach(View) onAttachedToWindow() onDetachedFromWindow() This Coordinator instance is then associated with the ViewGroup by storing it as a . This way, the coordinator can be obtained as , which is of course provided by class. tag Coordinator coordinator = (Coordinator)getTag(R.id.coordinator) Coordinators What is the benefit of this? Now that our class is a POJO, we can actually inject this class directly with Dagger, without having to specify a method in the Component. void inject(MyCustomViewGroup group); With that, we’ve obtained the following benefits: we do not need to inherit from a viewgroup and define 4 constructors in order to define our own “view controller” logic we can directly inject our newly made Coordinator directly from Dagger, without need for void inject(MyCoordinator coordinator) we no longer need a to create an instance of the “view”, we can just create a Coordinator instead Context Conclusion Personally, I like the direction that is taking. I’m not entirely sure if the and callbacks themselves are truly sufficient, but defining an and method of our own in our own class, then associating it with a isn’t exactly difficult either. Coordinators onAttachedToWindow() onDetachedFromWindow() attach(View) detach(View) tag In return, we receive a POJO view controller that can be directly created and injected via Dagger, without need of creating 4 constructors and hard-wiring the custom viewgroup in its own XML file. The new Coordinator approach works especially well if the navigation logic is detached from Activities/Fragments, and is moved to the Presenter layer. It makes for much cleaner code — application state transition isn’t something that the views should manage, after all. I took coordinators on a test drive in . https://github.com/Zhuinden/simple-stack/tree/master/simple-stack-example-mvp