$30 off During Our Annual Pro Sale. View Details »

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. Master of Android Theme
    DroidKaigi 2019

    2019/02/07 (Thu)

    @konifar

    View Slide

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

    View Slide

  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

    View Slide

  4. https://github.com/konifar/master-of-android-theme

    View Slide

  5. Android Theme

    View Slide

  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.

    View Slide

  7. themes.xml
    <br/><item name=“colorPrimary">@color/blue_grey_300</item><br/><item name=“colorPrimaryDark”>@color/blue_grey_400</item><br/><item name="colorAccent">@color/green_A200</item><br/>

    View Slide

  8. colorPrimary
    colorPrimaryDark
    colorAccent

    View Slide

  9. Two common problems

    View Slide

  10. 1. Too many parent themes

    View Slide

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

    View Slide

  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?

    View Slide

  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?

    View Slide

  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?

    View Slide

  15. 1. Apply theme

    View Slide

  16. ...
    android:theme="@style/AppTheme">


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

    View Slide

  17. ...
    android:theme="@style/AppTheme">


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

    View Slide

  18. Inheritance
    parent="Base.Theme.AppCompat.Light"/>
    <br/><item name="windowActionBar">false</item><br/><item name="windowNoTitle">true</item><br/>
    parent (higher priority than dot style)
    dot

    View Slide

  19. Inheritance
    parent="Base.Theme.AppCompat.Light"/>
    <br/><item name="windowActionBar">false</item><br/><item name="windowNoTitle">true</item><br/>
    parent (higher priority than dot style)
    dot
    Theme.AppCompat.Light.NoActionBar inherites Theme.AppCompat.Light
    with some attributes which is related to ActionBar.

    View Slide

  20. Inheritance
    parent="Base.Theme.AppCompat.Light"/>
    <br/><item name="windowActionBar">false</item><br/><item name="windowNoTitle">true</item><br/>
    parent (higher priority than dot style)
    dot

    View Slide

  21. When should we use parent
    inheritance style?

    View Slide

  22. When should we use parent inheritance?
    • Inherit the theme which is provided by the library like
    AppCompat, MaterialComponents.

    • Manage the API version differences.

    View Slide

  23. parent="Base.Theme.AppCompat.Light"/>

    View Slide

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

    View Slide

  25. parent=“Base.V21.Theme.AppCompat.Light”>
    res/values-v21/themes_base.xml
    parent="android:Theme.Material.Light.NoActionBar"><br/><!-- Update link colors pre-v23 --><br/><item name="android:textColorLink">?android:attr/colorAccent</item><br/>…<br/>
    parent="Base.Theme.AppCompat.Light"/>

    View Slide

  26. parent=“Base.V28.Theme.AppCompat.Light”>
    res/values-v28/themes_base.xml
    parent="Base.V26.Theme.AppCompat.Light"><br/><!-- We can use the platform styles on API 28+ --><br/><item name="dialogCornerRadius">?android:attr/dialogCornerRadius</item><br/>
    parent="Base.Theme.AppCompat.Light"/>

    View Slide

  27. Name rules of theme

    View Slide

  28. Theme.AppCompat.Light.DarkActionBar

    View Slide

  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

    View Slide

  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

    View Slide

  31. Theme.AppCompat ~.Light ~.DayNight
    Theme.AppCompat.Light.DarkActionBar
    Background brightness

    View Slide

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

    View Slide

  33. Theme.AppCompat.Light.DarkActionBar
    • AppCompat

    • MaterialComponents
    • (None)

    • Light

    • DayNight
    • (None)

    • DarkActionBar

    • NoActionBar
    We can find theme we want by combining these parts.

    View Slide

  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

    View Slide

  35. Change theme
    programmatically

    View Slide

  36. Activity
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Set before setContentView()
    setTheme(R.style.AppTheme)

    }

    View Slide

  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
    }

    View Slide

  38. Switch DayNight mode
    Programmatically

    View Slide

  39. DayNight theme
    parent="Theme.MaterialComponents.DayNight.NoActionBar" /><br/><item name=“android:textColor"><br/>@color/text_color<br/></item><br/><item name=“android:colorBackground”><br/>@color/background_color<br/></item><br/>…<br/>

    View Slide

  40. @color/blue_grey_900
    @color/blue_grey_50
    @color/blue_grey_900
    @color/blue_grey_50
    res/values/colors.xml
    res/values-night/colors.xml

    View Slide

  41. colorBackground
    textColor

    View Slide

  42. Change mode programmatically
    val mode = if (isNightMode) {
    AppCompatDelegate.MODE_NIGHT_YES
    } else {
    AppCompatDelegate.MODE_NIGHT_NO
    }
    activity.delegate.setLocalNightMode(mode)
    // Change mode immediately

    View Slide

  43. View Slide

  44. 2. Theme attributes

    View Slide

  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

    View Slide

  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

    View Slide

  47. Categories

    View Slide

  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

    View Slide

  49. https://material.io/design/material-studies/owl.html

    View Slide

  50. AppTheme

    View Slide

  51. fontFamily=“@font/rubik_medium”

    lineSpacingExtra

    TextAppearance
    textAppearanceBody1

    textAppearanceBody2

    textAppearanceButton

    textAppearanceHeadline1


    View Slide

  52. cornerFamily=“cut”

    cornerSize=“0dp”
    ShapeAppearance
    shapeAppearanceMediumComponent

    View Slide

  53. AppTheme.Personalize AppTheme.Browse AppTheme.Learn

    View Slide

  54. colorPrimary

    colorPrimaryVariant

    colorSecondary
    colorPrimary

    colorPrimaryVariant

    colorSecondary
    colorPrimary

    colorPrimaryVariant

    colorSecondary
    Color

    View Slide

  55. colorBackground

    textColor
    colorBackground

    textColor
    colorBackground

    textColor
    Color

    View Slide

  56. bottomNavigationStyle

    Widget.MaterialComponents.BottomNavigationView.Colored
    Widget style

    View Slide

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

    windowLightStatusBar=“true”

    View Slide

  58. parent="Theme.MaterialComponents.DayNight.NoActionBar">

    @color/…
    @color/…


    @style/…
    @style/..


    @style/…



    @style/…


    View Slide

  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
    ① ②

    View Slide

  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.

    View Slide

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

    View Slide

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

    View Slide

  63. Colors

    View Slide

  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

    View Slide

  65. New “colorOn~” for MaterialComponents
    • colorOnPrimary

    • colorOnSecondary

    • colorOnBackground

    • colorOnSurface

    • colorOnError

    View Slide

  66. colorOnSurface

    View Slide

  67. colorOnPrimary colorOnSecondary

    View Slide

  68. Text colors
    textColorPrimary
    textColorLink
    textColorHint
    editTextColor

    View Slide

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

    View Slide

  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


    View Slide

  71. Widget styles

    View Slide

  72. TabStyle

    View Slide

  73. TabStyle
    <br/><item name=“tabStyle">@style/App.Widget.Design.TabLayout</item><br/><style name=“App.Widget.Design.TabLayout"<br/>parent="Widget.Design.TabLayout"><br/><item name="elevation">4dp</item><br/><item name="android:background">?attr/colorPrimary</item><br/><item name="tabTextColor">?attr/textColorPrimaryInverse</item><br/>

    View Slide

  74. How can we find the widget
    style and attributes?

    View Slide

  75. Step1 : Search theme attribute
    • Input widget name which you want to change style.

    • The naming rule is “xxxStyle” like toolbarStyle, buttonStyle,
    checkBoxStyle.

    View Slide

  76. Step2 : Search default style
    • Input an expected default style.

    • The naming rule is “@style/Widget.~” like “Widget.AppCompat.Toolbar”

    View Slide

  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

    View Slide

  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


    View Slide

  79. Shape appearance

    View Slide

  80. • shapeAppearanceSmallComponent

    Buttons, Chips


    • shapeAppearanceMediumComponent

    Cards




    • shapeAppearanceLargeComponent

    Bottom Sheets


    View Slide

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

    View Slide

  82. parent="ShapeAppearance.MaterialComponents.SmallComponent"><br/><item name="cornerFamily">cut</item><br/><item name="cornerSize">8dp</item><br/>
    !OVMM EQ EQ EQ
    DVU
    SPVOEFE

    View Slide

  83. • chipStyle

    • materialCardViewStyle

    • buttonStyle

    • floatingActionButtonStyle
    ShapeAppearance in each widget style

    View Slide

  84. cut shape for FAB

    @style/Moat.FloatingActionButton
    parent="@style/Widget.MaterialComponents.FloatingActionButton"><br/><item name="shapeAppearanceOverlay">@style/Moat.ShapeAppearance.Fab</item><br/>

    parent="ShapeAppearance.MaterialComponents.SmallComponent"><br/><item name="cornerFamily">cut</item><br/><item name="cornerSize">@null</item><br/>

    View Slide

  85. Which should we use
    style or theme?

    View Slide

  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.

    View Slide

  87. https://material.io/design/material-studies/fortnightly.html
    textAppearance should be defined as theme

    View Slide

  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.

    View Slide

  89. Summary

    View Slide

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

    View Slide

  91. The most important thing is to
    know how to find the attributes
    you want to set.

    View Slide

  92. The colors and widget styles
    which should be defined as
    theme depends on the design

    View Slide

  93. Read the material design docs
    and use the material theming
    tools to use theme effectively.

    View Slide

  94. Have fun using Android theme!

    Thank you for

    your kind attention.

    View Slide