You are on page 1of 79

Styles,


Themes,

Material Theming, 

Oh My! 🙀

Anita Singh
@anitas3791
Styles,

Themes,

Material Theming, 

Oh My! 🙀

Anita Singh
@anitas3791
The problem

Style Theme

TextAppearance ThemeOverlay

Default Style? Material Theming?

…and they all use the style tag!


Style
What?

Key-value store, where the


key is an attribute
What?

Specifies the look of a single


view
Example

<style name=“WhiteTextButtonWidget"
parent=“Widget.MaterialComponents.Button">
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/cera_pro_bold</item>
</style>
Example

<style name=“WhiteTextButtonWidget"
parent=“Widget.MaterialComponents.Button">
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/cera_pro_bold</item>
</style>
Example

<style name=“WhiteTextButtonWidget"
parent=“Widget.MaterialComponents.Button">
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/cera_pro_bold</item>
</style>
Example

<style name=“WhiteTextButtonWidget"
parent=“Widget.MaterialComponents.Button">
<item name="android:textColor">@color/white</item>
<item name="android:fontFamily">@font/cera_pro_bold</item>
</style>

<Button
..
style=“@style/WhiteTextButtonWidget"
..
/>
When?

Applies to >1 logically related


components
TextAppearance
What?

Text specific styling, works


at the character level
Example

<style name="RaspberryTextAppearance">
<item name=“android:textColor”>@color/raspberry</item>
<item name=“android:fontFamily”>@font/cera_pro</item>
</style>
Example

<style name="RaspberryTextAppearance">
<item name=“android:textColor”>@color/raspberry</item>
<item name=“android:fontFamily”>@font/cera_pro</item>
</style>

<EditText

android:textAppearance="@style/RaspberryTextAppearance"
/>
When?

• You have a bloated style with text attributes


• You are only styling text at the character level
Theme
What?

A type of style applied to an


app or activity (or view)
What?

context.setTheme(resId)
Example

<style name="AppTheme"
parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/white</item>
<item name=“colorPrimaryVariant">@color/midnight</item>
<item name="colorSecondary">@color/blinkist_green</item>
<item name="colorControlNormal">@color/midnight</item>
<item name=“cardViewStyle”>@style/RoundCardViewStyle</item>

</style>
Example

<style name="AppTheme"
parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/white</item>
<item name=“colorPrimaryVariant">@color/midnight</item>
<item name="colorSecondary">@color/blinkist_green</item>
<item name="colorControlNormal">@color/midnight</item>
<item name=“cardViewStyle”>@style/RoundCardViewStyle</item>

</style>
Default Style Attribute
Example

<style name="AppTheme"
parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/white</item>
<item name="colorPrimaryDark">@color/midnight</item>
<item name="colorAccent">@color/blinkist_green</item>
<item name="colorControlNormal">@color/midnight</item>
<item name=“cardViewStyle”>@style/RoundCardViewStyle</item>

</style>

<application
android:theme=“@style/AppTheme"

/>
Theme attributes everywhere!

<selector>
<item android:color=“?attr/colorSecondary"
android:state_enabled="true"/>
<item android:alpha="0.6" android:color=“?attr/colorSecondary"/>
</selector>
Theme attributes everywhere!

<selector>
<item android:color=“?attr/colorSecondary"
android:state_enabled="true"/>
<item android:alpha="0.6" android:color=“?attr/colorSecondary"/>
</selector>
When?

• Style child views


• Implement a robust design system

ThemeOverlay
What?

View-level theming

minSdk 14+
What?

ContextThemeWrapper
Example

<Button
..
style="@style/Widget.AppCompat.Button.Colored"
android:theme=“@style/GreenButtonThemeOverlay”
/>
Example

<Button
..
style="@style/Widget.AppCompat.Button.Colored"
android:theme=“@style/GreenButtonThemeOverlay”
/>

<style name=“GreenButtonThemeOverlay">
<item name=“colorPrimary">@color/blinkist_green</item>
</style>
Example

<style name="ThemeOverlay.MaterialComponents"/>
<style name="ThemeOverlay.MaterialComponents.ActionBar"/>
<style name="ThemeOverlay.MaterialComponents.Dark"/>
<style name="ThemeOverlay.MaterialComponents.Dark.ActionBar"/>
<style name="ThemeOverlay.MaterialComponents.Dialog"/>
<style name="ThemeOverlay.MaterialComponents.Dialog.Alert"/>
<style name="ThemeOverlay.MaterialComponents.TextInputEditText"/>
When?

• Overlay an existing theme by changing only


what you need
• Invert the theme for a view or view hierarchy
Order of Precedence
Example

<style name="AppTheme"
parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/white</item>
<item name=“colorPrimaryVariant">@color/midnight</item>
<item name="colorSecondary">@color/blinkist_green</item>
<item name="colorControlNormal">@color/midnight</item>
<item name=“cardViewStyle”>@style/RoundCardViewStyle</item>

</style>
Default Style Attribute
How?

public CardView(@NonNull Context context, @Nullable AttributeSet attrs) {


this(context, attrs, R.attr.cardViewStyle);
}

public CardView(@NonNull Context context, @Nullable AttributeSet attrs, 



int defStyleAttr) {
super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CardView, defStyleAttr, R.style.CardView);


How?

public CardView(@NonNull Context context, @Nullable AttributeSet attrs) {


this(context, attrs, R.attr.cardViewStyle);
}

public CardView(@NonNull Context context, @Nullable AttributeSet attrs, 



int defStyleAttr) {
super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CardView, defStyleAttr, R.style.CardView);


How?

public CardView(@NonNull Context context, @Nullable AttributeSet attrs) {


this(context, attrs, R.attr.cardViewStyle);
}

public CardView(@NonNull Context context, @Nullable AttributeSet attrs, 



int defStyleAttr) {
super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CardView, defStyleAttr, R.style.CardView);
How?

public CardView(@NonNull Context context, @Nullable AttributeSet attrs) {


this(context, attrs, R.attr.cardViewStyle);
}

public CardView(@NonNull Context context, @Nullable AttributeSet attrs, 



int defStyleAttr) {
super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CardView, defStyleAttr, R.style.CardView)
Where the magic happens

getTheme().obtainStyledAttributes(
set, attrs, defStyleAttr, defStyleRes);
Styling Hierarchy

View

Style

Default Style

Theme

TextAppearance
Material Theming
What?
Material Components

A library of components,
evolution of Design Support
Library
Material Component Theme

• Theme.MaterialComponents.*

• Built on top of AppCompat


• Shiny new attributes!
• minSdk 14, compileSdk 28+
Color theming
Color theming
colorPrimaryVariant
colorOnPrimary
colorPrimary

background

colorOnSurface
surface

colorSecondary

colorOnSecondary
Color theming: new attributes

<item name="colorPrimaryVariant">..</item>
<item name=“colorOnPrimary">..</item>
<item name="colorSecondary">..</item>
<item name="colorSecondaryVariant">..</item>
<item name="colorOnSecondary">..</item>
<item name="colorSurface">..</item>
<item name="colorOnSurface">..</item>
<item name=“colorOnBackground">..</item>
<item name="colorOnError">..</item>
Shape theming

MaterialShapeDrawable
Shape theming
New attributes: shape

<item name=“shapeAppearanceSmallComponent">..</item>
<item name=“shapeAppearanceMediumComponent”>..</item>
<item name=“shapeAppearanceLargeComponent”>..</item>
New attributes: shape

<item name=“shapeAppearanceSmallComponent">..</item>
<item name=“shapeAppearanceMediumComponent”>..</item>
<item name=“shapeAppearanceLargeComponent”>..</item>
New attributes: shape

<item name=“shapeAppearanceSmallComponent">..</item>
<item name=“shapeAppearanceMediumComponent”>..</item>
<item name=“shapeAppearanceLargeComponent”>..</item>

<style ..parent="ShapeAppearance.MaterialComponents.S
mallComponent">
<item name="cornerFamilyTopLeft">cut</item>
<item name="cornerFamilyTopRight">cut</item>
<item name="cornerFamilyBottomLeft">rounded</item>
<item name="cornerFamilyBottomRight">rounded</item>
<item name="cornerSize">8dp</item>
</style>
New attributes: shape

<item name=“shapeAppearanceSmallComponent">..</item>
<item name=“shapeAppearanceMediumComponent”>..</item>
<item name=“shapeAppearanceLargeComponent”>..</item>

<style ..parent="ShapeAppearance.MaterialComponents
.SmallComponent">
<item name="cornerFamilyTopLeft">cut</item>
<item name="cornerFamilyTopRight">cut</item>
<item name="cornerFamilyBottomLeft">rounded</item>
<item name="cornerFamilyBottomRight">rounded</item>
<item name="cornerSize">8dp</item>
</style>
Typography theming
New attributes: typography

<item name="textAppearanceHeadline1"></item>
<item name="textAppearanceHeadline2"></item>
<item name="textAppearanceHeadline3"></item>
<item name="textAppearanceHeadline4"></item>
<item name="textAppearanceHeadline5"></item>
<item name="textAppearanceHeadline6"></item>
<item name="textAppearanceSubtitle1"></item>
<item name="textAppearanceSubtitle2"></item>
<item name=“textAppearanceBody1”></item>
<item name="textAppearanceBody2"></item>
<item name="textAppearanceCaption"></item>
<item name=“textAppearanceButton"></item>
<item name="textAppearanceOverline"></item>

Migrating to Material Component Theme

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

to

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">


Migrating to Material Component Theme

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

to

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">


You won’t believe what happened
next…
You won’t believe what happened
next…
You won’t believe what happened
next…
Migrating to Material Component Theme

android:background="@color/blinkist_green"
Migrating to Material Component Theme

android:background="@color/blinkist_green"

<style name="ButtonStyle"
parent="Widget.MaterialComponents.Button">
<item name="backgroundTint">@color/button_selector</item>

</style>
Migrating to Material Component Theme

android:background="@color/blinkist_green"

<style name="ButtonStyle"
parent="Widget.MaterialComponents.Button">
<item name="backgroundTint">@color/button_selector</item>

</style>
Migrating to Material Component Theme

android:background="@color/blinkist_green"

<style name="ButtonStyle"
parent="Widget.MaterialComponents.Button">
<item name="backgroundTint">@color/button_selector</item>

</style>


<item name=“materialButtonStyle">@style/ButtonStyle</item>

Migrating to Material Component Theme

Color of button background = colorPrimary

Option 2 : theme overlay set on button!

Option 3 : materialThemeOverlay set on default style!


Migrating to Material Component Theme

<style name="ButtonStyle"
parent="Widget.MaterialComponents.Button">
<item name=“materialThemeOverlay”>@style/
MidnightButtonThemeOverlay</item>

</style>

<style name="MidnightButtonThemeOverlay">
<item name="colorPrimary">@color/midnight</item>
</style>

…

<item name=“materialButtonStyle">@style/ButtonStyle</item>

Migrating to Material Component Theme

<style name=“…” parent="Widget.MaterialComponents.Button.Icon">


<item name="backgroundTint">@color/white</item>
<item name="icon">@drawable/ic_google</item>
<item name="iconTint">@null</item>
<item name="android:textColor">@color/mid_grey</item>
</style>
Migrating to Material Component Theme

<style name=“…” parent="Widget.MaterialComponents.Button.Icon">


<item name="backgroundTint">@color/white</item>
<item name="icon">@drawable/ic_google</item>
<item name="iconTint">@null</item>
<item name="android:textColor">@color/mid_grey</item>
</style>
Migrating to Material Component Theme

<style name=“…” parent="Widget.MaterialComponents.Button.Icon">


<item name="backgroundTint">@color/white</item>
<item name="icon">@drawable/ic_google</item>
<item name="iconTint">@null</item>
<item name="android:textColor">@color/mid_grey</item>
</style>
Migrating to Material Component Theme
Migrating to Material Component Theme

<style name="AlertDialogTheme"
parent="Theme.AppCompat.Light.Dialog.Alert">

to

<style name="AlertDialogTheme"
parent=“Theme.MaterialComponent.Light.Dialog.Alert">
Migrating to Material Component Theme

<style name="AlertDialogTheme"
parent="Theme.AppCompat.Light.Dialog.Alert">

to

<style name="AlertDialogTheme"
parent=“Theme.MaterialComponent.Light.Dialog.Alert">

Color of button text = colorPrimary


Migrating to Material Component Theme

..
<item name="textInputStyle">@style/
Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
..
Migrating to Material Component Theme

..
<item name="textInputStyle">@style/
Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
..
Color of selection = colorPrimary
Bridge Themes

Inherits from AppCompat,


but defines the new theme
attributes
Migrating to Material Component Theme

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

to
<style name="AppTheme"
parent=“Theme.MaterialComponents.Light.NoActionBar.Bridge”>
If something looks funny…

• Find the attribute(s) that matter


• What is the attribute being applied as – theme?
style?
• Order of Precedence. What could be overriding it?
• Have it extend a MaterialComponent style, if
present
• There are bugs!
Useful Links

• Material Theming Guide


• Material Components Github
• Material Theme Editor
• What's Your Text Appearance?
• Themes, Styles And More From Zero To Hero
• Android Themes & Styles Demystified
• Setting Up Material Components Theme For
Android
• The Components of Material Design
Thanks. anitas3791@gmail.com
@anitas3791

You might also like