responsive mobile design in practice

65
Responsive mobile design in practice Kirill Grouchnikov Android, Google Inc.

Upload: kirill-grouchnikov

Post on 10-May-2015

15.169 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Responsive mobile design in practice

Responsive mobile design in practice

Kirill GrouchnikovAndroid, Google Inc.

Page 2: Responsive mobile design in practice

this talk is about

minimizing the pain of developing for multiple form factors

Page 3: Responsive mobile design in practice

device variety

Archos 2.8”

Experia Pro 3.7” Flyer 7”

Galaxy Tab 8.9”

Sony Tablet S 9.4”

Galaxy Note 5.2” Toshiba Excite 13”

Page 4: Responsive mobile design in practice

device orientation

1024*600 600*1024

Page 5: Responsive mobile design in practice

adapting to the context

Page 6: Responsive mobile design in practice

maps

“show more” of the infinite canvas

Page 7: Responsive mobile design in practice

combine two (or more) screensin a multi-pane layout

settings

Page 8: Responsive mobile design in practice

promote two tabsinto the side panel

youtube (view)

Page 9: Responsive mobile design in practice

rearrange content in two columns

play store (details)

Page 10: Responsive mobile design in practice

responsive mobile design

Page 11: Responsive mobile design in practice

same content,same hierarchy

adapting to context

Page 13: Responsive mobile design in practice

same content,same hierarchy

adapting to context

Page 14: Responsive mobile design in practice

minimizing the pain of developing for multiple form factors

Page 15: Responsive mobile design in practice

same content, same hierarchydifferently stacked “blocks”

Page 16: Responsive mobile design in practice

summary

screenshots

byline

+1

description

Page 17: Responsive mobile design in practice

summaryscreenshotsdescriptionreviewsmore bydeveloper linkscross-sellflag content

rate & reviewauto-update (apps)trailer (movies)song list (albums)

Page 18: Responsive mobile design in practice

same blocksrearranged in two columns

Page 19: Responsive mobile design in practice
Page 20: Responsive mobile design in practice

same building block on the same screenon different form factors

Page 21: Responsive mobile design in practice

same building blockin different screens

Page 22: Responsive mobile design in practice
Page 23: Responsive mobile design in practice

res/layout/youtube_trailer_section.xml

<com.my.package.YoutubeTrailerSection> <ImageView android:id=”@+id/thumbnail” android:background=”black” /> <ImageView android:id=”@+id/play_icon” android:src=”@drawable/ic_video_play” /> <TextView android:id=”@+id/duration” android:textColor=”#CCCCCC” android:background=”#4C000000” android:textSize=”@dimen/content_primary” /></com.my.package.YoutubeTrailerSection>

Page 24: Responsive mobile design in practice

public class YoutubeTrailerSection extends TheMostSuitableBaseLayout

@Override onFinishInflate()bind(YoutubeTrailerData)

@Override onMeasure() - if needed@Override onLayout() - if needed

Page 25: Responsive mobile design in practice

<com.my.package.YoutubeTrailerSection> <ImageView android:id=”@+id/thumbnail” android:background=”black” /> <ImageView android:id=”@+id/play_icon” // ID not necessary if not used in code android:src=”@drawable/ic_video_play” /> <TextView android:id=”@+id/duration” android:textColor=”#CCCCCC” android:background=”#4C000000” android:textSize=”@dimen/content_primary” /></com.my.package.YoutubeTrailerSection>

private ImageView mThumbnail;private TextView mDuration;

@Overrideprotected void onFinishInflate() { super.onFinishInflate(); mThumbnail = (ImageView) findViewById(R.id.thumbnail); mDuration = (TextView) findViewById(R.id.duration);}

Page 26: Responsive mobile design in practice

private ImageView mThumbnail;private TextView mDuration;

@Overrideprotected void onFinishInflate() { super.onFinishInflate(); mThumbnail = (ImageView) findViewById(R.id.thumbnail); mDuration = (TextView) findViewById(R.id.duration);}

public void bind(YoutubeTrailerData data) { mDuration.setText(data.getFormattedLength()); String thumbnailUrl = data.getThumbnailUrl(); ImageUtils.load(mThumbnail, thumbnailUrl); // cache / network app code setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Intent youtubeIntent = IntentUtils.createYoutubeIntent( data.getVideoUrl()); getContext().startActivity(youtubeIntent); } });}

Page 27: Responsive mobile design in practice

why so much trouble with a custom class?

Page 28: Responsive mobile design in practice

encapsulation

Page 29: Responsive mobile design in practice

<include layout=”@layout/youtube_trailer_section” />

YoutubeTrailerSection trailer = (YoutubeTrailerSection) findViewById (R.id.youtube_trailer_section);trailer.bind(model.getYoutubeTrailerData());

Page 30: Responsive mobile design in practice

each block is binding a subset of the datano matter what the context is

Page 31: Responsive mobile design in practice

<include android:id=”@+id/summary_section” layout=”@layout/details_summary” /><include android:id=”@+id/screenshots_section” layout=”@layout/details_screenshots” /><include android:id=”@+id/byline_section” layout=”@layout/details_byline” /><include android:id=”@+id/plusone_section” layout=”@layout/details_plusone” /><include android:id=”@+id/description_section” layout=”@layout/details_text” />...

Page 32: Responsive mobile design in practice

ScreenshotsSection screenshots = (ScreenshotsSection) findViewById (R.id.screenshots_section);screenshots.bind(model.getScreenshotsData());

TextSection description = (TextSection) findViewById (R.id.description_section);description.bind(model.getDescriptionData());

* I can swear that some PMs seem to think that it’s really that simple

Page 33: Responsive mobile design in practice

the main flow looks up a section and passes the relevant data subset

Page 34: Responsive mobile design in practice

and each section handles its own data binding, events and layout

tweaks

Page 35: Responsive mobile design in practice

<include layout=”@layout/screenshots_section” />

ScreenshotsSection trailer = (ScreenshotsSection) findViewById (R.id.screenshots_section);trailer.bind(model.getScreenshotsData());

Page 36: Responsive mobile design in practice

no knowledge of context,internal IDs or event handling

Page 37: Responsive mobile design in practice

each block is a separate reusable layout

Page 38: Responsive mobile design in practice

include

include

includeinclude

include

include

includeincludeincludeinclude

include

include

include

include

Page 39: Responsive mobile design in practice

it’s like combining Lego blocks*

* except for the part where you’re stuck maintaining the code base

Page 40: Responsive mobile design in practice

all I see is <include>s

* he was kind of a douche, fell in love with the wrong girl and after that steak it really went downhill for him. YMMV.

Page 41: Responsive mobile design in practice

the code doesn’t have to be aware what is the context

Page 42: Responsive mobile design in practice

<include layout=”@layout/screenshots_section” />

ScreenshotsSection trailer = (ScreenshotsSection) findViewById (R.id.screenshots_section);trailer.bind(model.getScreenshotsData());

Page 43: Responsive mobile design in practice

welcome to the real world

Page 44: Responsive mobile design in practice

font size, column count, location of rating bar in cells

Page 45: Responsive mobile design in practice

font sizeres/values/font-dimens.xml <dimen name="content_primary_size">16sp</dimen>

res/values-sw800dp/font-dimens.xml <dimen name="content_primary_size">18sp</dimen>

res/values/styles.xml <style name="DetailsPage_Header"> ... <item name=”android:textSize”>@dimen/content_primary_size</item> </style>

res/layout/pack_header.xml <TextView android:id=”+id/header” style=”@style/DetailsPage_Header” ...

Page 46: Responsive mobile design in practice

column countres/values/ints.xml <integer name="moreby_items_per_row">2</integer>

res/values-sw800dp/ints.xml <integer name="moreby_items_per_row">1</integer>

public class MoreBySection private int mColumnCount;

public MoreBySection(Context ctx) { ... mColumnCount = ctx.getResources().getInteger( R.integer.moreby_items_per_row); }

Page 47: Responsive mobile design in practice

cell layoutsres/layout/item_cell.xmlres/layout-sw800dp/item_cell.xml

public class PackAdapter

@Override public View getView(int pos, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mLayoutInflater.inflate( R.layout.item_cell, parent, false); } CellViewHolder holder = (CellViewHolder) convertView.getTag(); ... return convertView; }

Page 48: Responsive mobile design in practice

the code doesn’t have to be aware what is the context*

* if you managed to confine the differences to resource files

Page 49: Responsive mobile design in practice

not exactly the same blocks

Page 50: Responsive mobile design in practice

context awareness “leaking” into the code

Page 51: Responsive mobile design in practice

res/values/bools.xml <bool name="use_two_column_layout">false</bool>

res/values-sw800dp/bools.xml <bool name="use_two_column_layout">true</bool>

Page 52: Responsive mobile design in practice

public class BylineSection

private boolean mIsTwoColumnMode;

public BylineSection(Context ctx) { ... mIsTwoColumnMode = ctx.getResources().getBoolean( R.bool.use_two_column_layout);}

public void bind() { if (mIsTwoColumnMode) { // add update date, download size and download count } else { // add rating count, update date, download size // and download count }}

Page 53: Responsive mobile design in practice

reuse blockson the same screen

on different form factors

Page 54: Responsive mobile design in practice

<include layout=”@layout/screenshots_section” />

ScreenshotsSection trailer = (ScreenshotsSection) findViewById (R.id.screenshots_section);trailer.bind(model.getScreenshotsData());

Page 55: Responsive mobile design in practice

reuse blocksin different screens

Page 56: Responsive mobile design in practice
Page 57: Responsive mobile design in practice
Page 58: Responsive mobile design in practice
Page 59: Responsive mobile design in practice
Page 60: Responsive mobile design in practice

<include layout=”@layout/youtube_trailer_section” />

YoutubeTrailerSection trailer = (YoutubeTrailerSection) findViewById (R.id.youtube_trailer_section);trailer.bind(model.getYoutubeTrailerData());

Page 61: Responsive mobile design in practice

“my apps” screen

Page 62: Responsive mobile design in practice

combine and share blocks

Page 63: Responsive mobile design in practice

this talk was about

minimizing the pain of developing for multiple form factors

Page 64: Responsive mobile design in practice

• identify

• encapsulate

• reuse

* almost made it through with no bullet points

building blocks

Page 65: Responsive mobile design in practice

Q&A

• slideshare.net/kirillcool

• pushing-pixels.org

• +Kirill Grouchnikov

[email protected]