Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Responsive mobiledesign in practice     Kirill Grouchnikov    Android, Google Inc.
this talk is aboutminimizing the pain of developing    for multiple form factors
device variety          Experia Pro 3.7”                  Flyer 7”                     Sony Tablet S 9.4”Archos 2.8”      ...
device orientation1024*600    600*1024
adapting to the context
maps“show more” of the infinite canvas
settingscombine two (or more) screens    in a multi-pane layout
youtube (view)  promote two tabs  into the side panel
play store (details)rearrange content in two columns
responsive mobile design
same content,  same hierarchyadapting to context
http://developer.android.com/design/patterns/multi-pane-layouts.html
same content,   same hierarchyadapting to context
minimizing the pain of developing    for multiple form factors
same content, same hierarchydifferently stacked “blocks”
summaryscreenshotsbyline+1description
summaryscreenshotsdescriptionreviewsmore bydeveloper linkscross-sellflag contentrate & reviewauto-update (apps)trailer (mov...
same blocksrearranged in two columns
same building block on the same screen     on different form factors
same building blockin different screens
res/layout/youtube_trailer_section.xml<com.my.package.YoutubeTrailerSection>    <ImageView        android:id=”@+id/thumbna...
public class YoutubeTrailerSection    extends TheMostSuitableBaseLayout@Override onFinishInflate()bind(YoutubeTrailerData)...
<com.my.package.YoutubeTrailerSection>    <ImageView        android:id=”@+id/thumbnail”        android:background=”black” ...
private ImageView mThumbnail;private TextView mDuration;@Overrideprotected void onFinishInflate() {    super.onFinishInfla...
why so much trouble with a      custom class?
encapsulation
<include    layout=”@layout/youtube_trailer_section” />YoutubeTrailerSection trailer =    (YoutubeTrailerSection) findView...
each block is binding a subset of the data  no matter what the context is
<include    android:id=”@+id/summary_section”    layout=”@layout/details_summary” /><include    android:id=”@+id/screensho...
ScreenshotsSection screenshots =                         (ScreenshotsSection) findViewById                              (R...
the main flow looks up a sectionand passes the relevant data subset
and each section handles its own data binding, events and layout             tweaks
<include    layout=”@layout/screenshots_section” />ScreenshotsSection trailer =    (ScreenshotsSection) findViewById      ...
no knowledge of context,internal IDs or event handling
each block is a separate reusable layout
include                include          includeinclude                includeinclude   includeinclude   include   include ...
it’s like combining Lego blocks*  * except for the part where you’re stuck maintaining the code base
all I see is <include>s* he was kind of a douche, fell in love with the wrong girl and afterthat steak it really went down...
the code doesn’t have to be  aware what is the context
<include    layout=”@layout/screenshots_section” />ScreenshotsSection trailer =    (ScreenshotsSection) findViewById      ...
welcome to the real world
font size, column count,location of rating bar in cells
font sizeres/values/font-dimens.xml   <dimen name="content_primary_size">16sp</dimen>res/values-sw800dp/font-dimens.xml   ...
column countres/values/ints.xml   <integer name="moreby_items_per_row">2</integer>res/values-sw800dp/ints.xml   <integer n...
cell layoutsres/layout/item_cell.xmlres/layout-sw800dp/item_cell.xmlpublic class PackAdapter   @Override   public View get...
the code doesn’t have to be  aware what is the context*  * if you managed to confine the differences to resource files
not exactly the same blocks
context awareness “leaking”      into the code
res/values/bools.xml   <bool name="use_two_column_layout">false</bool>res/values-sw800dp/bools.xml   <bool name="use_two_c...
public class BylineSectionprivate boolean mIsTwoColumnMode;public BylineSection(Context ctx) {    ...    mIsTwoColumnMode ...
reuse blocks  on the same screenon different form factors
<include    layout=”@layout/screenshots_section” />ScreenshotsSection trailer =    (ScreenshotsSection) findViewById      ...
reuse blocksin different screens
<include    layout=”@layout/youtube_trailer_section” />YoutubeTrailerSection trailer =    (YoutubeTrailerSection) findView...
“my apps” screen
combine and share blocks
this talk was aboutminimizing the pain of developing    for multiple form factors
building blocks•identify• encapsulate• reuse * almost made it through with no bullet points
Q&A• slideshare.net/kirillcool• pushing-pixels.org• +Kirill Grouchnikov• kirillcool@yahoo.com
Responsive mobile design in practice
Responsive mobile design in practice
Responsive mobile design in practice
Responsive mobile design in practice
Responsive mobile design in practice
Responsive mobile design in practice
Upcoming SlideShare
Loading in …5
×

Responsive mobile design in practice

20,145 views

Published on

Published in: Technology, News & Politics

Responsive mobile design in practice

  1. 1. Responsive mobiledesign in practice Kirill Grouchnikov Android, Google Inc.
  2. 2. this talk is aboutminimizing the pain of developing for multiple form factors
  3. 3. device variety Experia Pro 3.7” Flyer 7” Sony Tablet S 9.4”Archos 2.8” Galaxy Note 5.2” Galaxy Tab 8.9” Toshiba Excite 13”
  4. 4. device orientation1024*600 600*1024
  5. 5. adapting to the context
  6. 6. maps“show more” of the infinite canvas
  7. 7. settingscombine two (or more) screens in a multi-pane layout
  8. 8. youtube (view) promote two tabs into the side panel
  9. 9. play store (details)rearrange content in two columns
  10. 10. responsive mobile design
  11. 11. same content, same hierarchyadapting to context
  12. 12. http://developer.android.com/design/patterns/multi-pane-layouts.html
  13. 13. same content, same hierarchyadapting to context
  14. 14. minimizing the pain of developing for multiple form factors
  15. 15. same content, same hierarchydifferently stacked “blocks”
  16. 16. summaryscreenshotsbyline+1description
  17. 17. summaryscreenshotsdescriptionreviewsmore bydeveloper linkscross-sellflag contentrate & reviewauto-update (apps)trailer (movies)song list (albums)
  18. 18. same blocksrearranged in two columns
  19. 19. same building block on the same screen on different form factors
  20. 20. same building blockin different screens
  21. 21. 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>
  22. 22. public class YoutubeTrailerSection extends TheMostSuitableBaseLayout@Override onFinishInflate()bind(YoutubeTrailerData)@Override onMeasure() - if needed@Override onLayout() - if needed
  23. 23. <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);}
  24. 24. 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); } });}
  25. 25. why so much trouble with a custom class?
  26. 26. encapsulation
  27. 27. <include layout=”@layout/youtube_trailer_section” />YoutubeTrailerSection trailer = (YoutubeTrailerSection) findViewById (R.id.youtube_trailer_section);trailer.bind(model.getYoutubeTrailerData());
  28. 28. each block is binding a subset of the data no matter what the context is
  29. 29. <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” />...
  30. 30. 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
  31. 31. the main flow looks up a sectionand passes the relevant data subset
  32. 32. and each section handles its own data binding, events and layout tweaks
  33. 33. <include layout=”@layout/screenshots_section” />ScreenshotsSection trailer = (ScreenshotsSection) findViewById (R.id.screenshots_section);trailer.bind(model.getScreenshotsData());
  34. 34. no knowledge of context,internal IDs or event handling
  35. 35. each block is a separate reusable layout
  36. 36. include include includeinclude includeinclude includeinclude include include includeinclude include include
  37. 37. it’s like combining Lego blocks* * except for the part where you’re stuck maintaining the code base
  38. 38. all I see is <include>s* he was kind of a douche, fell in love with the wrong girl and afterthat steak it really went downhill for him. YMMV.
  39. 39. the code doesn’t have to be aware what is the context
  40. 40. <include layout=”@layout/screenshots_section” />ScreenshotsSection trailer = (ScreenshotsSection) findViewById (R.id.screenshots_section);trailer.bind(model.getScreenshotsData());
  41. 41. welcome to the real world
  42. 42. font size, column count,location of rating bar in cells
  43. 43. 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” ...
  44. 44. 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); }
  45. 45. cell layoutsres/layout/item_cell.xmlres/layout-sw800dp/item_cell.xmlpublic 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; }
  46. 46. the code doesn’t have to be aware what is the context* * if you managed to confine the differences to resource files
  47. 47. not exactly the same blocks
  48. 48. context awareness “leaking” into the code
  49. 49. 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>
  50. 50. public class BylineSectionprivate 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 }}
  51. 51. reuse blocks on the same screenon different form factors
  52. 52. <include layout=”@layout/screenshots_section” />ScreenshotsSection trailer = (ScreenshotsSection) findViewById (R.id.screenshots_section);trailer.bind(model.getScreenshotsData());
  53. 53. reuse blocksin different screens
  54. 54. <include layout=”@layout/youtube_trailer_section” />YoutubeTrailerSection trailer = (YoutubeTrailerSection) findViewById (R.id.youtube_trailer_section);trailer.bind(model.getYoutubeTrailerData());
  55. 55. “my apps” screen
  56. 56. combine and share blocks
  57. 57. this talk was aboutminimizing the pain of developing for multiple form factors
  58. 58. building blocks•identify• encapsulate• reuse * almost made it through with no bullet points
  59. 59. Q&A• slideshare.net/kirillcool• pushing-pixels.org• +Kirill Grouchnikov• kirillcool@yahoo.com

×