Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Android Theme

Slide 6

Slide 6 text

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.

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

colorPrimary colorPrimaryDark colorAccent

Slide 9

Slide 9 text

Two common problems

Slide 10

Slide 10 text

1. Too many parent themes

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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?

Slide 13

Slide 13 text

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?

Slide 14

Slide 14 text

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?

Slide 15

Slide 15 text

1. Apply theme

Slide 16

Slide 16 text


 
 AndroidManifest.xml themes.xml

Slide 17

Slide 17 text


 
 AndroidManifest.xml themes.xml

Slide 18

Slide 18 text

Inheritance <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> parent (higher priority than dot style) dot

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Inheritance <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> parent (higher priority than dot style) dot

Slide 21

Slide 21 text

When should we use parent inheritance style?

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Name rules of theme

Slide 28

Slide 28 text

Theme.AppCompat.Light.DarkActionBar

Slide 29

Slide 29 text

• 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

Slide 30

Slide 30 text

• 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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Theme.AppCompat.Light.DarkActionBar • AppCompat • MaterialComponents • (None) • Light • DayNight • (None) • DarkActionBar • NoActionBar We can find theme we want by combining these parts.

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

Change theme programmatically

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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 }

Slide 38

Slide 38 text

Switch DayNight mode Programmatically

Slide 39

Slide 39 text

DayNight theme @color/text_color @color/background_color …

Slide 40

Slide 40 text

@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

Slide 41

Slide 41 text

colorBackground textColor

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

2. Theme attributes

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Categories

Slide 48

Slide 48 text

• 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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

AppTheme

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

AppTheme.Personalize AppTheme.Browse AppTheme.Learn

Slide 54

Slide 54 text

colorPrimary
 colorPrimaryVariant
 colorSecondary colorPrimary
 colorPrimaryVariant
 colorSecondary colorPrimary
 colorPrimaryVariant
 colorSecondary Color

Slide 55

Slide 55 text

colorBackground
 textColor colorBackground
 textColor colorBackground
 textColor Color

Slide 56

Slide 56 text

bottomNavigationStyle
 Widget.MaterialComponents.BottomNavigationView.Colored Widget style

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

<!-- 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>

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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.

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Colors

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

New “colorOn~” for MaterialComponents • colorOnPrimary • colorOnSecondary • colorOnBackground • colorOnSurface • colorOnError

Slide 66

Slide 66 text

colorOnSurface

Slide 67

Slide 67 text

colorOnPrimary colorOnSecondary

Slide 68

Slide 68 text

Text colors textColorPrimary textColorLink textColorHint editTextColor

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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


Slide 71

Slide 71 text

Widget styles

Slide 72

Slide 72 text

TabStyle

Slide 73

Slide 73 text

TabStyle <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>

Slide 74

Slide 74 text

How can we find the widget style and attributes?

Slide 75

Slide 75 text

Step1 : Search theme attribute • Input widget name which you want to change style. • The naming rule is “xxxStyle” like toolbarStyle, buttonStyle, checkBoxStyle.

Slide 76

Slide 76 text

Step2 : Search default style • Input an expected default style. • The naming rule is “@style/Widget.~” like “Widget.AppCompat.Toolbar”

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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


Slide 79

Slide 79 text

Shape appearance

Slide 80

Slide 80 text

• shapeAppearanceSmallComponent
 Buttons, Chips
 
 • shapeAppearanceMediumComponent
 Cards
 
 
 
 • shapeAppearanceLargeComponent
 Bottom Sheets


Slide 81

Slide 81 text

<item name="cornerFamily">cut</item> <item name="cornerSize">8dp</item>

Slide 82

Slide 82 text

<item name="cornerFamily">cut</item> <item name="cornerSize">8dp</item> !OVMM EQ EQ EQ DVU SPVOEFE

Slide 83

Slide 83 text

• chipStyle • materialCardViewStyle • buttonStyle • floatingActionButtonStyle ShapeAppearance in each widget style

Slide 84

Slide 84 text

cut shape for FAB @style/Moat.FloatingActionButton <item name="shapeAppearanceOverlay">@style/Moat.ShapeAppearance.Fab</item> 
 <item name="cornerFamily">cut</item> <item name="cornerSize">@null</item>

Slide 85

Slide 85 text

Which should we use style or theme?

Slide 86

Slide 86 text

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.

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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.

Slide 89

Slide 89 text

Summary

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

Have fun using Android theme! Thank you for your kind attention.