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

Using styles and themes without going crazy

Using styles and themes without going crazy

Presented at Droidcon NYC 2015.

Daniel Lew

August 27, 2015
Tweet

More Decks by Daniel Lew

Other Decks in Programming

Transcript

  1. • No style <View android:background=“#FF0000” /> • Style <!--- some_layout.xml

    --> <View style="@style/MyStyle" /> <!--- styles.xml -->
 <style name="MyStyle">
 <item name="android:background">#FF0000</item>
 </style>
  2. When NOT to style • Single-use styles • Coincidentally using

    the same attributes <TextView
 android:id="@+id/title"
 android:textColor="@color/blue_200"
 android:textColorHint=“@color/grey_500" />
 
 <TextView
 android:id="@+id/body"
 android:textColor="@color/blue_200"
 android:textColorHint=“@color/grey_500" />
  3. When NOT to style • Single-use styles • Coincidentally using

    the same attributes <TextView
 android:id="@+id/title"
 android:textColor="@color/blue_200"
 android:textColorHint=“@color/grey_500" />
 
 <TextView
 android:id="@+id/body"
 android:textColor="@color/blue_200"
 android:textColorHint=“@color/grey_500" />
  4. When NOT to style • Single-use styles • Coincidentally using

    the same attributes <TextView
 android:id="@+id/title"
 android:textColor="@color/blue_200"
 android:textColorHint=“@color/grey_500" />
 
 <TextView
 android:id="@+id/body"
 android:textColor="@color/blue_200"
 android:textColorHint=“@color/grey_500" />
  5. static final int NUM_COLUMNS = 3;
 
 static final int

    NUM_RETRIES = 3; static final int NUM_THREE = 3;
  6. // static final int NUM_COLUMNS = 3;
 
 // static

    final int NUM_RETRIES = 3;
 static final int NUM_THREE = 3;
  7. • Parent <style name="Parent" /> • Explicit child <style name="Child"

    parent="Parent" /> • Implicit child <style name="Parent.Child" />
  8. Custody Battle <style name="Implicit" />
 
 <style name="Explicit" /> <style

    name="Implicit.Child" parent="Explicit" /> • Who gets the child? • Choices: • Both • Implicit • Explicit
  9. • Explicit parent -> dotless child <style name="BorderlessButton"
 parent="Widget.AppCompat.Button.Borderless" />

    • Fake it! <style name="Widget.Button"
 parent="Widget.AppCompat.Button" />
 
 <style name="Widget.Button.Borderless"
 parent="Widget.AppCompat.Button.Borderless" />
  10. TextAppearance Attributes • textColor • textColorHighlight • textColorHint • textColorLink

    • textSize • textStyle • fontFamily • typeface • textAllCaps • shadowColor • shadowDx • shadowDy • shadowRadius • elegantTextHeight • letterSpacing • fontFeatureSettings
  11. TextAppearance • In action <TextView
 style="@style/MyStyle"
 android:textAppearance="@style/MyText"
 /> • Always

    inherit TextAppearance! <style name="MyText" parent="TextAppearance.AppCompat">
 <item name="android:textColor">#F00</item>
 </style>
  12. Themes! • Write a whole lot of UX code at

    once! • Setup defaults for everything! • Activity-level theming! • Configure system-created Views! • Theme swapping!
  13. Themes vs. Styles • Same thing! <style name="Style">
 <item name="android:background">#FF0000</item>


    </style> <style name="Theme">
 <item name="android:statusBarColor">@color/blue_200</item>
 </style> • Different scope • Different attributes
  14. Use AppCompat • Material on all devices • Baseline themes/styles

    • Enables View theming pre-Lollipop • …And more!
  15. Default Styles <style name="AppTheme" parent="Theme.AppCompat">
 <item name="buttonStyle">@style/MyButton</item>
 <item name="android:spinnerItemStyle">@style/MySpinnerItem</item>
 


    <item name="android:textAppearance">@style/MyText</item>
 <item name="android:textAppearanceInverse">@style/MyTextInverse</item>
 </style>
  16. Namespacing • Official attributes <style name="MyTheme">
 <item name="android:colorPrimary">#000</item>
 </style> •

    Custom attributes <style name="MyTheme" parent="Theme.AppCompat">
 <item name="colorPrimary">#000</item>
 </style> v21 only appcompat magic
  17. Finding Attributes • Most difficult part of themes • Anyone

    can create attributes • Anything can use attributes
  18. Attributes in XML • Look for ?attr or ?android:attr <Button

    android:background="?attr/selectableItemBackground" />
  19. View Style Attributes • Look for obtainStyledAttributes() TypedArray a =

    context.obtainStyledAttributes(attrs,
 com.android.internal.R.styleable.ImageView, defStyleAttr, defStyleRes); • Investigate TypedArray usage int alpha = a.getInt(com.android.internal.R.styleable.ImageView_drawableAlpha, 255); attribute default
  20. Recipe for Sanity • Use AppCompat • Modify theme first

    • Reference theme attributes • Apply themes to Views when necessary • Use styles wisely
  21. <style name="MyTheme" parent="Theme.AppCompat">
 <item name="android:windowBackground">@color/bg_window</item>
 </style> <!-- values/colors.xml -->
 <color

    name="bg_window">#FF0000</color>
 
 <!-- values-v21/colors.xml -->
 <color name="bg_window">#0000FF</color>
  22. <!-- values/styles.xml -->
 <style name="BaseToolbar" />
 
 <!-- values-v21/styles.xml -->


    <style name="BaseToolbar">
 <item name="android:elevation">4dp</item>
 </style> <!-- values/styles.xml -->
 <style name="Toolbar" parent="BaseToolbar" /> <!-- values/styles.xml -->
 <style name="BaseToolbar" />
 
 <!-- values-v21/styles.xml -->
 <style name="BaseToolbar">
 <item name="android:elevation">4dp</item>
 </style>
  23. Custom Attributes <!-- values/attrs.xml -->
 <attr name="myAttribute" format="dimension" />
 


    <!-- values/themes.xml -->
 <style name="MyTheme" parent="Theme.AppCompat">
 <item name="myAttribute">4dp</item>
 </style>
 
 <!-- values/styles.xml -->
 <style name="MyStyle">
 <item name="android:padding">?attr/myAttribute</item>
 </style>
  24. Custom Attributes <!-- values/attrs.xml -->
 <attr name="myAttribute" format="dimension" />
 


    <!-- values/themes.xml -->
 <style name="MyTheme" parent="Theme.AppCompat">
 <item name="myAttribute">4dp</item>
 </style>
 
 <!-- values/styles.xml -->
 <style name="MyStyle">
 <item name="android:padding">?attr/myAttribute</item>
 </style>
  25. Custom Attributes <!-- values/attrs.xml -->
 <attr name="myAttribute" format="dimension" />
 


    <!-- values/themes.xml -->
 <style name="MyTheme" parent="Theme.AppCompat">
 <item name="myAttribute">4dp</item>
 </style>
 
 <!-- values/styles.xml -->
 <style name="MyStyle">
 <item name="android:padding">?attr/myAttribute</item>
 </style>
  26. Dynamic Styles public View(Context context, AttributeSet attrs, int defStyleAttr, int

    defStyleRes) themed context layout attributes default style (v21+) default style attribute (from theme, e.g. buttonStyle)
  27. Dynamic Styles • Context carries theme • ContextThemeWrapper replaces parts

    of theme Context themedContext = new ContextThemeWrapper(baseContext, R.style.MyTheme);
 
 // Use in LayoutInflater
 View view = LayoutInflater.from(themedContext) .inflate(R.layout.my_layout, null);
 
 // Use in View constructor
 View view = new View(themedContext);