""Building complex UIs on Android is difficult enough on its own, but when you start making your app modular, your UI breaks down. This talk covers some of the ideas I came up with over the years to address that problem.
Discussing how to build complex UIs on Android is a very wide topic. I will try to cover some of the things you can do to make your life easier. This talk is divided into 3 segments:
- Architecture (options, design patterns)
- Organizing Android components
- Making UI modular
Organizing things like this helps a lot with scaling the app from a few simple fragments to tens of different, module- or feature-limited, standalone app screens."
17. Android layouts
● Less layouts; more styles
● Print and slice UI on paper
● Sub-layouts belong to static containers
● Use phone UI in tablet containers
21. MVP - Variations
Passive View
● View not aware of the Model
● Presenter does the hard work
Supervising Controller
● View interacts directly with the Model
● Presenter handles extreme cases
24. Lifecycle
● Service, Activity, Fragment, Dialog,
Application - all different
● Create a custom UI entity? I do it anyway
● Unreliability, bugs, appcompat, gotchas
● API levels…
● Fragment caching mechanism…
Solution: Move away from Android APIs?
28. Asynchronous work
● UI events must go to a UI thread
● Long operations go on a background thread
● Thread or AsyncTask or RxJava
● Events? Otto or GreenRobot or others
● A swarm of events
Advice: Keep it minimal for your needs
29. Self-contained UI parts (Pages)
● Keep pages focused on the UI
● Presenters prepare data for pages
● Pages handle dialogs internally
● Complex dialogs? Contain pages inside them
● Persistent presenters or Presenter pool?
Advice: Instantiate in one place
30. Android Activity
● Context is everywhere
● Difficult to decouple
● Components: LoaderManager, Cursor,
FragmentManager, Fragment backstack,
Fragment caching, Content Providers,
Intents, Menus, etc.
Advice: It’s worth decoupling, try to do it
31. Intents
● Handle all intents in one place
● Allow the IntentHandler to navigate
● Use an ActivityResolver
● Allow easy Activity switching
Advice: React in onResume() method if possible
33. Rules for a ‘happy’ UI
● Enumerate pages somehow (enum optimized?)
● Pages need a common navigation API
● Framework creates (and caches) pages
● Follow the Activity lifecycle
Example of a ‘happy’ UI code:
navigate().with(myBundle).to(Pages.LOGIN);
34. Show and hide pages (Page Manager)
● Static containers or dynamic containers
● Watch out: component lifecycles
● Decoupled mechanism for show/hide
● The dark pit of FragmentManager
Advice: Small app - use FragmentManager
Big app - build your own PageManager
35. Layout and navigation (The Coordinator)
● Decoupled navigation & layout component
● Uses the PageManager to show/hide
● Handles back and “up”
● Holds the IntentHandler component
Advice: Make Coordinator also a page, a
‘super-page’ that holds all other pages
36. Visible UI on Phones Actual layers on Phones
The Coordinator
Content Page
Navigation drawer page
37. The Coordinator
Branding bar
List page
Details page
FAB
List Page
Toolbar & menu
List
- Item photo
- Item name
Details Page
Toolbar & menu
Large title
Content
Actual layers on Tablets
38. Page Modularity
External configuration causes trouble
● A lot of if-else branches in pages
● Custom Views rule the app (learning curve)
Solution: Have a distinct page for each UI
Advice: Create a PageResolver component
39. Drawbacks
● A lot of decoupling and cosmetic work
● A lot of method references
● Difficult to switch to
● Makes sense only for complex UIs
● Team education
● Limited support (open-source?)
40. To recap...
● Self-maintained UI components (pages)
● Data is always prepared (presenters)
● Intent handling happens in one place
● Page Resolver helps with modular UIs
● Separate navigation mechanism
● Wrap it all up in a Coordinator
● Have a Coordinator for each screen variant