Master of Android Theme

35e08efcf39d692f540047fb756eb4e3?s=47 konifar
February 07, 2019

Master of Android Theme

35e08efcf39d692f540047fb756eb4e3?s=128

konifar

February 07, 2019
Tweet

Transcript

  1. Master of Android Theme DroidKaigi 2019 2019/02/07 (Thu) @konifar

  2. @konifar https://github.com/konifar/

  3. 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
  4. https://github.com/konifar/master-of-android-theme

  5. Android Theme

  6. 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.
  7. themes.xml <style name=“AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar"> <item name=“colorPrimary">@color/blue_grey_300</item> <item name=“colorPrimaryDark”>@color/blue_grey_400</item> <item name="colorAccent">@color/green_A200</item>

    </style>
  8. colorPrimary colorPrimaryDark colorAccent

  9. Two common problems

  10. 1. Too many parent themes

  11. 2. Too many attributes android:windowLightStatusBar android:actionMenuTextColor android:windowBackground android:textColor android:disabledAlpha colorButtonNormal

    colorSwitchThumbNormal textColorLink
  12. 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?
  13. 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?
  14. 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?
  15. 1. Apply theme

  16. <application ... android:theme="@style/AppTheme">
 
 <activity android:name=".MainActivity" android:theme=“@style/AppTheme"> <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">

    AndroidManifest.xml themes.xml
  17. <application ... android:theme="@style/AppTheme">
 
 <activity android:name=".MainActivity" android:theme=“@style/AppTheme"> <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">

    AndroidManifest.xml themes.xml
  18. 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
  19. 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.
  20. 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
  21. When should we use parent inheritance style?

  22. When should we use parent inheritance? • Inherit the theme

    which is provided by the library like AppCompat, MaterialComponents. • Manage the API version differences.
  23. parent="Base.Theme.AppCompat.Light"/>

  24. <style name="Base.Theme.AppCompat.Light" parent=“Base.V7.Theme.AppCompat.Light"></style> parent="Base.Theme.AppCompat.Light"/> res/values/themes_base.xml <style name=“Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light"> <item name=“viewInflaterClass”>androidx…</item>

    … </style>
  25. <style name="Base.Theme.AppCompat.Light" parent=“Base.V21.Theme.AppCompat.Light”></style> res/values-v21/themes_base.xml <style name=“Base.V21.Theme.AppCompat.Light" parent="android:Theme.Material.Light.NoActionBar"> <!-- Update link

    colors pre-v23 --> <item name="android:textColorLink">?android:attr/colorAccent</item> … </style> parent="Base.Theme.AppCompat.Light"/>
  26. <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"/>
  27. Name rules of theme

  28. Theme.AppCompat.Light.DarkActionBar

  29. • 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
  30. • 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
  31. Theme.AppCompat ~.Light ~.DayNight Theme.AppCompat.Light.DarkActionBar Background brightness

  32. ~.AppCompat.Light ~.Light.DarkActionBar ~.NoActionBar NoActionBar is used with ToolBar Theme.AppCompat.Light.DarkActionBar ActionBar(Toolbar)

    brightness
  33. Theme.AppCompat.Light.DarkActionBar • AppCompat • MaterialComponents • (None) • Light •

    DayNight • (None) • DarkActionBar • NoActionBar We can find theme we want by combining these parts.
  34. 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
  35. Change theme programmatically

  36. Activity override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Set before

    setContentView() setTheme(R.style.AppTheme) … }
  37. 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 }
  38. Switch DayNight mode Programmatically

  39. DayNight theme <style name=“AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar" /> <item name=“android:textColor"> @color/text_color </item>

    <item name=“android:colorBackground”> @color/background_color </item> … </style>
  40. <color name="text_color">@color/blue_grey_900</color> <color name=“background_color”>@color/blue_grey_50</color> <color name="text_color">@color/blue_grey_900</color> <color name=“background_color”>@color/blue_grey_50</color> res/values/colors.xml res/values-night/colors.xml

  41. colorBackground textColor

  42. Change mode programmatically val mode = if (isNightMode) { AppCompatDelegate.MODE_NIGHT_YES

    } else { AppCompatDelegate.MODE_NIGHT_NO } activity.delegate.setLocalNightMode(mode) // Change mode immediately
  43. None
  44. 2. Theme attributes

  45. 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
  46. 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
  47. Categories

  48. • 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
  49. https://material.io/design/material-studies/owl.html

  50. AppTheme

  51. fontFamily=“@font/rubik_medium”
 lineSpacingExtra
 TextAppearance textAppearanceBody1
 textAppearanceBody2
 textAppearanceButton
 textAppearanceHeadline1
 …

  52. cornerFamily=“cut”
 cornerSize=“0dp” ShapeAppearance shapeAppearanceMediumComponent

  53. AppTheme.Personalize AppTheme.Browse AppTheme.Learn

  54. colorPrimary
 colorPrimaryVariant
 colorSecondary colorPrimary
 colorPrimaryVariant
 colorSecondary colorPrimary
 colorPrimaryVariant
 colorSecondary Color

  55. colorBackground
 textColor colorBackground
 textColor colorBackground
 textColor Color

  56. bottomNavigationStyle
 Widget.MaterialComponents.BottomNavigationView.Colored Widget style

  57. Window configuration v19 windowTranslucentStatus=“true” V21 statusBarColor=“@android:color/transparent” V23 statusBarColor=“@android:color/transparent"
 windowLightStatusBar=“true”

  58. <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>
  59. • 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 ① ② ③
  60. 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.
  61. https://github.com/konifar/android-theme-attrs-to-markdown-table/blob/ master/outputs/color_attrs.md

  62. https://github.com/konifar/android-theme-attrs-to-markdown-table/blob/ master/outputs/color_attrs.md

  63. Colors

  64. 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
  65. New “colorOn~” for MaterialComponents • colorOnPrimary • colorOnSecondary • colorOnBackground

    • colorOnSurface • colorOnError
  66. colorOnSurface

  67. colorOnPrimary colorOnSecondary

  68. Text colors textColorPrimary textColorLink textColorHint editTextColor

  69. Component colors colorButtonNormal colorControlActivated colorSwitchThumbNormal colorControlNormal colorForeground colorControlHighlight (Ripple color)

  70. 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

  71. Widget styles

  72. TabStyle

  73. 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>
  74. How can we find the widget style and attributes?

  75. Step1 : Search theme attribute • Input widget name which

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

    style. • The naming rule is “@style/Widget.~” like “Widget.AppCompat.Toolbar”
  77. 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
  78. 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

  79. Shape appearance

  80. • shapeAppearanceSmallComponent
 Buttons, Chips
 
 • shapeAppearanceMediumComponent
 Cards
 
 


    
 • shapeAppearanceLargeComponent
 Bottom Sheets

  81. <style name=“Moat.ShapeAppearance.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent"> <item name="cornerFamily">cut</item> <item name="cornerSize">8dp</item> </style>

  82. <style name=“Moat.ShapeAppearance.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent"> <item name="cornerFamily">cut</item> <item name="cornerSize">8dp</item> </style> !OVMM EQ

    EQ EQ DVU SPVOEFE
  83. • chipStyle • materialCardViewStyle • buttonStyle • floatingActionButtonStyle ShapeAppearance in

    each widget style
  84. 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>
  85. Which should we use style or theme?

  86. 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.
  87. https://material.io/design/material-studies/fortnightly.html textAppearance should be defined as theme

  88. https://material.io/design/material-studies/fortnightly.html It might be better to define this search edit

    text as style, not theme. Chip style should be defined as theme.
  89. Summary

  90. There are many theme attributes, but they are categorized to

    only seven types.
  91. The most important thing is to know how to find

    the attributes you want to set.
  92. The colors and widget styles which should be defined as

    theme depends on the design
  93. Read the material design docs and use the material theming

    tools to use theme effectively.
  94. Have fun using Android theme! Thank you for your kind

    attention.