milos marinkovic "modular android ui"
TRANSCRIPT
A visual introduction
What does it mean to have a Modular UI?
Responsive layouts
Adjust padding and View positions on larger screens
Different item lists on different devices
List presented as Grid on larger screens
Runtime-configurable layouts
Different list arrangement on larger screens
Displaying the same content in different containers
Compress layout vertically in split-screen scenario
Different navigation on different devices
Architecture & Layering
Android SDK helps.. with some stuff
● Screen sizes: small, normal, large, xlarge● Screen aspect ratio: long, notlong● Device orientation: land, port● Screen densities: ldpi, mdpi, hdpi, xhdpi,
xxhdpi, xxxhdpi● Density pixels (dp) instead of pixels (px)● Precise screen sizes: w__dp, h__dp, sw__dp
Phones
Small Tablets (7”, 8”)
Large Tablets
Android layouts
● Less layouts; more styles● Print and slice UI on paper● Sub-layouts belong to static containers● Use phone UI in tablet containers
MVC
Model:View:Controller
● Model - SQLite, Shared prefs
● View - main_activity.xml, ListFragment.java
● Controller - MyController.java, MainActivity.java (don’t)
MVVM
Model:View:ViewModel
● Model - SQLite, Shared prefs
● View - main_activity.xml, ViewGroup or View,
AccountListFragment.java● ViewModel - AccountListFragmentUiModel.java
MVP
Model:View:Presenter
● Model - SQLite, Shared prefs
● View - main_activity.xml, ViewGroup or View
● Presenter - MainActivity.java ListFragment.java
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
Components for Android
How we dividedAndroid components
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?
Fragment lifecycle...
Android Lists with RecyclerView
● Decouple!● Android: Recycler View, Adapter, Layout
Manager, Item Animator, Item Decorator, Recycled Pool, Cache, Item Decoration
Advice: Split “adapter” component (1) data provider and (2) recycler adapter
Recycler overview
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
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
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
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
Connecting the dots
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);
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
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
Visible UI on Phones Actual layers on Phones
The Coordinator
Content Page
Navigation drawer page
The CoordinatorBranding barList pageDetails pageFAB
List PageToolbar & menuList - Item photo - Item name
Details PageToolbar & menuLarge titleContent
Actual layers on Tablets
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 UIAdvice: Create a PageResolver component
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?)
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
Finally done.Modular Android UI
GitHub / Twitter / LinkedIn
@ milosmns
Blog
www.angrybyte.me
Questions?