Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Master of Android Theme

konifar
February 07, 2019

Master of Android Theme

konifar

February 07, 2019
Tweet

More Decks by konifar

Other Decks in Programming

Transcript

  1. Kyash • I work for Japanese Fintech company called Kyash.

    • It makes easy to create Visa card and send money to anyone via app! https://play.google.com/store/apps/details?id=co.kyash
  2. Android Theme Overview • Technically the same as Style. •

    Theme is “Global”, Style is “Local”. • It’s important to use Theme especially since Material Design appeared.
  3. Today I’ll talk about 1. Apply theme
 - Which parent

    theme should we implement?
 - How should we inherit and manage themes?
 - How can we change theme and night mode dynamically? 2. Theme attributes
 - Which attributes affect where?
 - How can we find all the attributes for AppCompat and Material Components?
 - Which should we apply theme or style?
  4. Today I’ll talk about 1. Apply theme
 - Which parent

    theme should we implement?
 - How should we inherit and manage themes?
 - How can we change theme and night mode dynamically? 2. Theme attributes
 - Which attributes affect where?
 - How can we find all the attributes for AppCompat and Material Components?
 - Which should we apply theme or style?
  5. Today I’ll talk about 1. Apply theme
 - Which parent

    theme should we implement?
 - How should we inherit and manage themes?
 - How can we change theme and night mode dynamically? 2. Theme attributes
 - Which attributes affect where?
 - How can we find all the attributes for AppCompat and Material Components?
 - Which should we apply theme or style?
  6. Inheritance <style name="Theme.AppCompat.Light" parent="Base.Theme.AppCompat.Light"/> <style name="Theme.AppCompat.Light.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item>

    </style> parent (higher priority than dot style) dot Theme.AppCompat.Light.NoActionBar inherites Theme.AppCompat.Light with some attributes which is related to ActionBar.
  7. When should we use parent inheritance? • Inherit the theme

    which is provided by the library like AppCompat, MaterialComponents. • Manage the API version differences.
  8. <style name="Base.Theme.AppCompat.Light" parent=“Base.V28.Theme.AppCompat.Light”></style> res/values-v28/themes_base.xml <style name=“Base.V28.Theme.AppCompat.Light" parent="Base.V26.Theme.AppCompat.Light"> <!-- We can

    use the platform styles on API 28+ --> <item name="dialogCornerRadius">?android:attr/dialogCornerRadius</item> </style> parent="Base.Theme.AppCompat.Light"/>
  9. • Theme
 All theme we use is named with `Theme`

    prefix. • ThemeOverlay
 Special themes that overlay the base theme and redefine some of the properties to be applied to a specific views. Theme.AppCompat.Light.DarkActionBar Prefix
  10. • AppCompat
 Defined in https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/ appcompat/res/values/themes.xml • MaterialComponents
 Defined in

    https://github.com/material-components/material-components-android/blob/ master/lib/java/com/google/android/material/theme/res/values/themes.xml • Design
 Same as AppCompat. Just alias defined by MaterialComponents. Theme.AppCompat.Light.DarkActionBar Theme (Library) name
  11. Theme.AppCompat.Light.DarkActionBar • AppCompat • MaterialComponents • (None) • Light •

    DayNight • (None) • DarkActionBar • NoActionBar We can find theme we want by combining these parts.
  12. Theme.MaterialComponents.Light.DarkActionBar.Bridge parent=“Theme.MaterialComponents.Light.DarkActionBar.Bridge”> // parent=“Theme.AppCompat.Light.DarkActionBar”> Bridge themes inherit from AppCompat themes,

    but also define the mandatory new Material Components theme attributes to migrate to MaterialComponents easily.
 https://github.com/material-components/material-components-android/blob/master/docs/getting- started.md#bridge-themes-bridge-themes
  13. Fragment override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?

    ): View? { val contextThemeWrapper = ContextThemeWrapper(activity, R.style.AppTheme) val localInflater = inflater.cloneInContext(contextThemeWrapper) val view = localInflater.inflate( R.layout.fragment_main, container, false ) return view.rootView }
  14. Change mode programmatically val mode = if (isNightMode) { AppCompatDelegate.MODE_NIGHT_YES

    } else { AppCompatDelegate.MODE_NIGHT_NO } activity.delegate.setLocalNightMode(mode) // Change mode immediately
  15. Read code • Android Framework
 https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/themes.xml
 https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/attrs.xml • AppCompat
 https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/themes_base.xml


    https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/attrs.xml • MaterialComponents
 https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/theme/ res/values/themes_base.xml
 https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/theme/ res/values/attrs.xml
  16. Read code • Android Framework
 https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/themes.xml
 https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/attrs.xml • AppCompat
 https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/themes_base.xml


    https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/attrs.xml • MaterialComponents
 https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/theme/ res/values/themes_base.xml
 https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/theme/ res/values/attrs.xml
  17. • Colors
 colorPrimary
 colorSecondary • Drawables
 selectableItemBackground
 editTextBackground • Text

    appearances
 textAppearance
 textAppearanceMedium • Shape appearances
 shapeAppearanceSmallComponent
 shapeAppearanceMediumComponent • Widget styles
 actionBarStyle
 tabStyle • Themes
 actionBarTheme
 dialogTheme • Window configurations
 windowNoTitle
 windowActionBar
  18. <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- Colors --> <item name=“colorPrimary”>@color/…</item> <item name=“colorPrimaryVariant”>@color/…</item>


    <!-- Text appearances --> <item name=“textAppearanceBody1”>@style/…</item> <item name=“textAppearanceBody2”>@style/..</item>
 <!-- ShapeAppearances --> <item name=“shapeAppearanceMediumComponent”>@style/…</item>
 
 <!-- Widget styles --> <item name=“bottomNavigationStyle”>@style/…</item>
 <!-- Window configurations—> <item name=“windowTranslucentStatus”>true</item> </style>
  19. • Colors
 colorPrimary
 colorSecondary • Drawables
 selectableItemBackground
 editTextBackground • Text

    appearances
 textAppearance
 textAppearanceMedium • Shape appearances
 shapeAppearanceSmallComponent
 shapeAppearanceMediumComponent • Widget styles
 actionBarStyle
 tabStyle • Themes
 actionBarTheme
 dialogTheme • Window configurations
 windowNoTitle
 windowActionBar ① ② ③
  20. Attributes reference list • I summarized all the attributes per

    each categories to a simple markdown table.
 https://github.com/konifar/android-theme-attrs-to-markdown-table • This repository would be help you to find the attribute and know each meaning.
  21. https://material.io/develop/android/theming/color/ AppCompat MaterialComponents Example colorPrimary colorPrimary Toolbar colorPrimaryDark colorPrimaryVariant StatusBar

    colorAccent colorSecondary FAB, ProgressBar colorBackground colorBackground Background colorBackgroundFloating colorSurface CardView Differences between AppCompat and MC
  22. Colors appendix • All attributes are here
 https://github.com/konifar/android-theme-attrs-to-markdown-table/blob/master/outputs/color_attrs.md • Default

    values are defined in themes_base.xml
 Android Platform: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/ themes.xml
 AppCompat: https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/ themes_base.xml
 Material Components: https://github.com/material-components/material-components-android/blob/master/lib/java/ com/google/android/material/theme/res/values/themes_base.xml

  23. TabStyle <style name="AppTheme" parent=“…”> <item name=“tabStyle">@style/App.Widget.Design.TabLayout</item> <style name=“App.Widget.Design.TabLayout" parent="Widget.Design.TabLayout"> <item

    name="elevation">4dp</item> <item name="android:background">?attr/colorPrimary</item> <item name="tabTextColor">?attr/textColorPrimaryInverse</item> </style>
  24. Step1 : Search theme attribute • Input widget name which

    you want to change style. • The naming rule is “xxxStyle” like toolbarStyle, buttonStyle, checkBoxStyle.
  25. Step2 : Search default style • Input an expected default

    style. • The naming rule is “@style/Widget.~” like “Widget.AppCompat.Toolbar”
  26. Step3 : Search style attributes • I usually search on

    GitHub repository. AppCompat: https://github.com/aosp-mirror/platform_frameworks_support/blob/master/appcompat/res/values/styles_base.xml
 MaterialComponents: https://github.com/material-components/material-components-android/find/master
  27. Widget styles appendix • All attributes are here
 https://github.com/konifar/android-theme-attrs-to-markdown-table/blob/master/outputs/widget_style_attrs.md •

    Default values are defined in themes_base.xml
 Android Platform: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/ styles.xml
 AppCompat: https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/ styles_base.xml
 Material Components: Each styles.xml in https://github.com/material-components/material-components-android/tree/ master/lib/java/com/google/android/material

  28. cut shape for FAB <!—- themes.xml —-> <item name="floatingActionButtonStyle">@style/Moat.FloatingActionButton</item> <style

    name=“Moat.FloatingActionButton” parent="@style/Widget.MaterialComponents.FloatingActionButton"> <item name="shapeAppearanceOverlay">@style/Moat.ShapeAppearance.Fab</item> </style> 
 <style name=“Moat.ShapeAppearance.Fab" parent="ShapeAppearance.MaterialComponents.SmallComponent"> <item name="cornerFamily">cut</item> <item name="cornerSize">@null</item> </style>
  29. Depends on the design • We can customize almost widget

    by using theme. • If the design is common in the app, it should be defined as theme. • If the widget font or shape is specific in the app, it should be defined as style and apply it in layout.xml.
  30. The most important thing is to know how to find

    the attributes you want to set.