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

Transcript

60 slides
  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);

More Decks by Daniel Lew

Other Decks in Programming