You are on page 1of 58

AWESOME ANDROID DESIGN

Nick Butcher +Android Developers

ANDROID DEVELOPER RELATIONS


Nick Butcher google.com/+NickButcher | @crafty

androiddesigninaction.com

+NickButcher

Awesome Android Design


WHY VISUAL LANGUAGE

HOLO

RESPONSIVE DESIGN

TECHNIQUES IMPLEMENTING TOOLS

Holo Visual Language

Holo Visual Language

Content First

Content First
Borderless buttons

Button bar

Typography
Roboto Thin & Thin Oblique Roboto Light & Light Oblique

Hello, Roboto

Roboto Regular & Regular Oblique Roboto Medium & Medium Oblique Roboto Bold & Bold Oblique Roboto Black & Black Oblique Roboto Condensed & Condensed Oblique Roboto Bold Condensed Bold Condensed Oblique

USE TYPOGRAPHY
to provide STRUCTURE and emphasis

Colour

Holo != #33b5e5

Colour
Use your brand colour for accent Use high-contrast colour for emphasis

Colour
Touch feedback
Holo Light: 20% #999 (#33999999) Holo Dark: 25% #ccc (#40cccccc)
Jolt of high contrast Sprinkles of encouragement

Branding
Information Design Interaction Design Visual Design

You

Holo/Android

android-holo-colors.com

TOOLS

ANDROID HOLO COLORS Generate Holo assets for UI controls, using your brands accent color

actionbarstylegenerator.com

TOOLS

ACTION BAR STYLE GENERATOR Generate Holo assets for the action bar and tabs, using your brands accent color

Implementing Holo

Themes
Inherit from Holo styles
minSdkVersion 11+ res/values/styles.xml <style name="MyTheme" parent="android:Theme.Holo.Light"/> minSdkVersion 711 res/values/styles.xml <style name="MyTheme" parent="Theme.AppCompat.Light"/> AndroidManifest.xml <application ... theme="@style/MyTheme">

Use the framework


Reference styles, dimensions and drawables from the current theme
<View style="?android:foo" .../> <View android:minHeight="?android:bar" .../> <View android:background="?android:baz" .../>

(eqivilant to ?android:attr/baz)

Current theme value

See android.R.attr for all style attributes

Use the framework

Use the framework


14sp, bold, ALL CAPS 2dp separator
<TextView style="?android:listSeparatorTextViewStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Section header" />

Use the framework


<TextView android:textAppearance= "?android:textAppearanceMedium" android:text="Sample item 1" ... />

18sp

Stateful background

<ImageButton style="?android:borderlessButtonStyle" ... />

Use the framework


<LinearLayout android:orientation="vertical" android:showDividers="middle" android:divider="?android:dividerHorizontal" ...> <LinearLayout android:orientation="horizontal" android:baselineAligned="false" android:showDividers="middle" android:divider="?android:dividerVertical" android:dividerPadding="8dp" ...>

Padding creates hierarchy

Use the framework


<LinearLayout style="?android:buttonBarStyle" ...> <Button style="?android:buttonBarButtonStyle" ...>

Adds dividers

Stateful background

Style the framework


MainActivity#onCreate requestWindowFeature( Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.activity_main); ... setProgressBarIndeterminateVisibility(true);

Activity indicator

Style the framework


<style name="MyTheme" parent="..."> <item name="android:actionBarStyle">@style/ActionBar</item> </style> <style name="ActionBar" parent="..."> <item name="android:indeterminateProgressStyle"> @style/Widget.ActionBar.ActivityIndicator</item> </style> <style name="Widget.ActionBar.ActivityIndicator" parent="..."> <item name="android:minWidth">48dp</item> <item name="android:maxWidth">48dp</item> <item name="android:minHeight">32dp</item> <item name="android:maxHeight">32dp</item> </style>

Styled activity indicator

Query theme values


Control inset by Action Bar height

Query theme values


TypedValue value = new TypedValue(); getActivity().getTheme().resolveAttribute( android.R.attr.actionBarSize, value, true); int actionBarSize = getResources() .getDimensionPixelSize(value.resourceId); // now inset the map control getMap().setPadding(0, actionBarSize, 0, 0);

Responsive Design

Why responsive?

Why responsive?

Combining content

Combining content
res/ ... layout/ activity_home.xml activity_details.xml fragment_list.xml fragment_details.xml layout-sw720dp/ activity_home.xml ...

Combining content
res/ ... layout/ activity_home.xml activity_details.xml fragment_list.xml fragment_details.xml layout-sw720dp/ activity_home.xml ...

Combining content
res/ ... layout/ activity_home.xml activity_details.xml fragment_list.xml fragment_details.xml layout-sw720dp/ activity_home.xml ...

Combining content
res/ ... layout/ activity_home.xml activity_details.xml fragment_list.xml fragment_details.xml layout-sw720dp/ activity_home.xml ...

Combining content
SlidingPaneLayout

Combining content
SlidingPaneLayout
<android.support.v4.widget.SlidingPaneLayout ... android:layout_width="match_parent" android:layout_height="match_parent"> <!-- First child is the left pane --> <fragment android:name="com.example.ListFragment" android:layout_width="280dp" android:layout_height="match_parent" android:layout_gravity="start" /> <!-- Second child is the right (content) pane --> <fragment android:name="com.example.DetailFragment" android:layout_width="600dp" android:layout_height="match_parent" android:layout_weight="1" /> </android.support.v4.widget.SlidingPaneLayout>

If combined pane widths exceed screen width then right pane overlaps

Lists and grids

Lists and grids


res/layout/activity_home.xml <GridView ... android:numColumns="@integer/num_columns" /> res/values/integers.xml <resources> <integer name="num_columns">1</integer> </resources> res/values-w500dp/integers.xml <resources> <integer name="num_columns">2</integer> </resources>

Lists and grids


MyAdapter#getView if (convertView == null) { int numColumns = getResources().getInteger(R.integer.num_columns); if (numColumns == 1) { convertView = inflater.inflate(R.layout.list_item_layout, parent, false); } else { convertView = inflater.inflate(R.layout.grid_item_layout, parent, false); } } ...

Staggered grid

https://github.com/etsy/ AndroidStaggeredGrid

Inside out design

Inside out design

Going Responsive with Google Play


http://goo.gl/ceytgQ

Extract dimensions
res/values/dimens.xml <dimen <dimen <dimen <dimen <dimen name="default_spacing_major">16dp</dimen> name="default_spacing_minor">8dp</dimen> name="default_spacing_micro">4dp</dimen> name="body_text_size">18sp</dimen> name="body_line_spacing" format="float" type="dimen">1.0</dimen>

default_spacing_major headline_text_size body_text_size body_line_spacing

res/values-sw720dp/dimens.xml <dimen name="default_spacing_major">32dp</dimen> <dimen name="body_text_size">20sp</dimen> <dimen name="body_line_spacing" format="float" type="dimen">1.2</dimen>

Maximum widths
Avoid overly wide line lengths for comfortable reading Optimal measure is 4575 chars per line

Maximum widths
<com.example.MaxWidthLinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical"> ! <TextView app:layout_maxWidth="600dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/lorem_ipsum" ... /> </com.example.MaxWidthLinearLayout>

MaxWidthLinearLayout
http://goo.gl/zNY0jy

Responsive images
<ImageView android:scaleType="centerCrop" android:src="@drawable/bacon" android:layout_width="match_parent" android:layout_height="match_parent" />

1dp separator

Use the resources framework


res/ ... drawable/ drawable-xhdpi/ layout/ layout-w600dp/ layout-sw600dp-land/ layout-sw720dp/ values/ values-sw600dp/ values-sw720dp/ ... Alternate density drawables for crispness Alternate layouts for different sized displays Alternate dimensions for different sized displays

Tips for designers

Use an Android phone and learn its patterns

Map your information design to android navigation patterns

http://youtu.be/zhszwkcay2A

Know your pixels from your DIPs

Design layout at MDPI i.e. 1px = 1dp

Consider

scale from the start

Awesome Android Design


WHY VISUAL LANGUAGE

HOLO

RESPONSIVE DESIGN

TECHNIQUES IMPLEMENTING TOOLS

Thanks!
Nick Butcher +Android Developers

You might also like