IMPROVING ANDROID EXPERIENCE FORBOTH USERS AND DEVELOPERSdroidcon Berlin 2013, Pavel Lahoda,Actiwerks Ltd.
LET’S HAVE A LITTLE WARMUP
ANDROID.UTIL.LOG
HOW MANYTIMESYOU’VETYPEDTHIS ?
prn.log("Index=" + i);HOW ABOUTTHIS ?
public static String cc(int depth) {	 	 if(skipCallStackCode == true) {	 	 	 return NA; // short-circuit for production	 	...
GITHUB LINK
WHERE ISTHE UX ?
HAVE TIME TO WORK ON AWESOMESTUFF !
IMPORTANCE OF HAVINGYOUR VIEW FLEXIBLE
ANDROID AND WEB COMMON STUFFUNLIMITED AMOUNT OF DISPLAY SIZES
WEBTRENDS: RESPONSIVE DESIGN
ANDROIDTRENDS: LOTS OF WORK
CURRENT ANDROID LAYOUTS ARENOT FLEXIBLE ENOUGH
ALTERNATIVE:USE PURE JAVAVIEWGROUP
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSpecSize = View.MeasureSpec.getSi...
ONMEASURE() - PLACE FORYOUR LOGIC
NO NEEDTO REBIND COMPONENTS ORCALL SLOW LAYOUT INFLATE CODE
WORKS GREAT FOR ORIENTATIONCHANGES
BBC NEWS FORTABLETS EXAMPLE
INSPIRATION:WEB RESPONSIVE LAYOUT
DEAL WITH MANY DIFFERENT SCREENSIZES
STANDOUT - FLOATING WINDOWS
ACTION BAR
ONE OF WORST EXAMPLESOF API DESIGN
ACTIONBAR IS NOT A DESCENDANT OFAVIEW
BLOG.PERPETUMDESIGN.COM/2011/08/STRANGE-CASE-OF-DR-ACTION-AND-MR-BAR.HTML
ACTIONBARSHERLOCK
ACTION BAR PLUS
PROBLEM ?
AB OCCUPIES ~10% OF SCREEN SPACE
FUNCTIONALITY OFTEN REDUCEDTOBRANDING
FLY-OUT MENU:A FACEBOOK SOLUTION
NOT CONSISTENT WITHTHE REST OFACTIONBAR FUNCTIONALITY
ACTIONBAR PARTS
ACTIONBAR BEHAVIORTouch here showsa menu with optionsTouch here moves up in hierarchyTouch here performs actionTouch here ...
DON’T CONFUSEYOUR USERS
OWN APPS’D USE SOME UX FACELIFT
STILL WANT MORE FROMTHEACTIONBAR AREA ?
ACTION BAR PLUSCUSTOM ACTIONBAR IMPLEMENTATION
EMBRACE EXTRA DIMENSION
TWOTYPES OF NAVIGATION
MAKE SURETHERE IS DEAD AREATOSEPARATE FROM NOTIFICATION BARGESTURE
USE MIDDLE AS BONUS CONTENT
SUCH AS STUFF OUTSIDETHE APP
2D JUST ON OVERFLOWACTIONS ARE EITHERTOUCHOR SWIPE DOWN
ACCESSTO HELP ON ACTIONS
EMBRACE MULTITOUCH
EASY SPLITVIEW FEATURE
BROADCASTTHE AVAILABLE SCREENactiwerks.intent.splitviewDESCRIPTION OFTHE INTENT APPEARS SOON ONTHE OPENINTENTS.ORG
BROADCAST DETAILSprivate Intent splitIntent;splitIntent = new Intent();splitIntent.setAction("actiwerks.intent.splitview")...
RECEIVETHE BROADCAST<receiver android:name="AppSplitViewReceiver" ><intent-filter><action android:name="actiwerks.intent.s...
ACTIONBARPLUS INTHE GITHUB
FUN WITHTHE LISTVIEW
PROBLEM ?
ARRAYADAPTER API NOT DESIGNEDFOR GENERICVIEWGROUP
interface ViewAdapterBinder<T, V> {public void bindViewToData(V view, T data);}public class ArrayViewGroupAdapter<T, V ext...
public View getView(int position, View convertView, ViewGroup parent){	 		 // assign the view we are converting to a local...
private V getInstanceOfV() {ParameterizedType superClass = (ParameterizedType)getClass().getGenericSuperclass();	 Class<V>...
public class SampleArrayAdapter extends ArrayViewGroupAdapter<SampleData, SampleListItem> {	 public SampleArrayAdapter(Con...
ATYPE-SAFE, REFACTORING FRIENDLYSOLUTION
ADVANTAGES FORTHE DEVELOPER ANDTHE USER
INSTANT LISTS WITH INTROSPECTION
OBJECTFORMS.COM
FLEXIBLE LAYOUT ALLOWS RESIZING
PINCHTO ZOOM GESTURE IN LISTS
TIME AND DATE PICKER
PROBLEM ?
UNLIKE OTHER WIDGETS,TIME & DATE PICKER NEEDS DIALOG(OR PLENTY OF SPACE)
SOLUTION:SPLIT EDITING INTO SPECIALIZEDTIME & DATE KEYBOARD
DIRECT MANIPULATION GESTURE
“KEYBOARD” FOR DATE SELECTION
NOTOUCH AT ALL
KINETIC GESTURES
SHAKE GESTURE- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{if (motion == UIEventSubtypeMotionShake...
AREATHAT IS NOT GETTINGTHE LOVEIT DESERVERS
TIM BRAY : SENSPLORE
SENSOR FUSIONhttp://www.youtube.com/watch?v=C7JQ7Rpwn2k
SAMSUNG GESTURES
HELP US SHAPETHE FUTUREhttp://www.kineticgestures.org
TAKEWAY
Q & A
THANKYOU
PAVEL LAHODAPAVEL@ACTIWERKS.COM@PERPETUMDESIGN
Droidcon2013 android experience lahoda
Upcoming SlideShare
Loading in...5
×

Droidcon2013 android experience lahoda

379

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
379
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Droidcon2013 android experience lahoda

  1. 1. IMPROVING ANDROID EXPERIENCE FORBOTH USERS AND DEVELOPERSdroidcon Berlin 2013, Pavel Lahoda,Actiwerks Ltd.
  2. 2. LET’S HAVE A LITTLE WARMUP
  3. 3. ANDROID.UTIL.LOG
  4. 4. HOW MANYTIMESYOU’VETYPEDTHIS ?
  5. 5. prn.log("Index=" + i);HOW ABOUTTHIS ?
  6. 6. public static String cc(int depth) { if(skipCallStackCode == true) { return NA; // short-circuit for production } StackTraceElement[] ste = getStackTrace(null); int depthCount = 0; boolean shallowFlag = true; for(StackTraceElement element : ste) { if(prn.class.getName().equals(element.getClassName()) == true) { // always ignore elements that are above this class in the stack shallowFlag = false; } else { if(shallowFlag == false) { if(depthCount >= depth) { String name = element.getFileName(); if(name != null) { if(name.endsWith(".java")) { name = name.substring(0, name.length()-5); } } else { name ="[?]"; } return name; } else { depthCount++; } } } } return NA_BUG; }HOW DOES IT WORK ?
  7. 7. GITHUB LINK
  8. 8. WHERE ISTHE UX ?
  9. 9. HAVE TIME TO WORK ON AWESOMESTUFF !
  10. 10. IMPORTANCE OF HAVINGYOUR VIEW FLEXIBLE
  11. 11. ANDROID AND WEB COMMON STUFFUNLIMITED AMOUNT OF DISPLAY SIZES
  12. 12. WEBTRENDS: RESPONSIVE DESIGN
  13. 13. ANDROIDTRENDS: LOTS OF WORK
  14. 14. CURRENT ANDROID LAYOUTS ARENOT FLEXIBLE ENOUGH
  15. 15. ALTERNATIVE:USE PURE JAVAVIEWGROUP
  16. 16. @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec); tinyGap = widthSpecSize/100; myComponent.measure(View.MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY));// more component’s measuring goes there setMeasuredDimension(widthSpecSize, newHeight);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {myComponent.layout(x, y, x+myComponent.getMeasuredWidth(), y+titleLabel.getMeasuredHeight());// more component’s layout goes there}
  17. 17. ONMEASURE() - PLACE FORYOUR LOGIC
  18. 18. NO NEEDTO REBIND COMPONENTS ORCALL SLOW LAYOUT INFLATE CODE
  19. 19. WORKS GREAT FOR ORIENTATIONCHANGES
  20. 20. BBC NEWS FORTABLETS EXAMPLE
  21. 21. INSPIRATION:WEB RESPONSIVE LAYOUT
  22. 22. DEAL WITH MANY DIFFERENT SCREENSIZES
  23. 23. STANDOUT - FLOATING WINDOWS
  24. 24. ACTION BAR
  25. 25. ONE OF WORST EXAMPLESOF API DESIGN
  26. 26. ACTIONBAR IS NOT A DESCENDANT OFAVIEW
  27. 27. BLOG.PERPETUMDESIGN.COM/2011/08/STRANGE-CASE-OF-DR-ACTION-AND-MR-BAR.HTML
  28. 28. ACTIONBARSHERLOCK
  29. 29. ACTION BAR PLUS
  30. 30. PROBLEM ?
  31. 31. AB OCCUPIES ~10% OF SCREEN SPACE
  32. 32. FUNCTIONALITY OFTEN REDUCEDTOBRANDING
  33. 33. FLY-OUT MENU:A FACEBOOK SOLUTION
  34. 34. NOT CONSISTENT WITHTHE REST OFACTIONBAR FUNCTIONALITY
  35. 35. ACTIONBAR PARTS
  36. 36. ACTIONBAR BEHAVIORTouch here showsa menu with optionsTouch here moves up in hierarchyTouch here performs actionTouch here show a menu with optionsAny extension should stay consistent with this
  37. 37. DON’T CONFUSEYOUR USERS
  38. 38. OWN APPS’D USE SOME UX FACELIFT
  39. 39. STILL WANT MORE FROMTHEACTIONBAR AREA ?
  40. 40. ACTION BAR PLUSCUSTOM ACTIONBAR IMPLEMENTATION
  41. 41. EMBRACE EXTRA DIMENSION
  42. 42. TWOTYPES OF NAVIGATION
  43. 43. MAKE SURETHERE IS DEAD AREATOSEPARATE FROM NOTIFICATION BARGESTURE
  44. 44. USE MIDDLE AS BONUS CONTENT
  45. 45. SUCH AS STUFF OUTSIDETHE APP
  46. 46. 2D JUST ON OVERFLOWACTIONS ARE EITHERTOUCHOR SWIPE DOWN
  47. 47. ACCESSTO HELP ON ACTIONS
  48. 48. EMBRACE MULTITOUCH
  49. 49. EASY SPLITVIEW FEATURE
  50. 50. BROADCASTTHE AVAILABLE SCREENactiwerks.intent.splitviewDESCRIPTION OFTHE INTENT APPEARS SOON ONTHE OPENINTENTS.ORG
  51. 51. BROADCAST DETAILSprivate Intent splitIntent;splitIntent = new Intent();splitIntent.setAction("actiwerks.intent.splitview");splitIntent.removeExtra("APP_SPLIT_SIZE");splitIntent.putExtra("APP_SPLIT_SIZE", windowVerticalOffset);getContext().sendBroadcast(splitIntent);
  52. 52. RECEIVETHE BROADCAST<receiver android:name="AppSplitViewReceiver" ><intent-filter><action android:name="actiwerks.intent.splitview" /></intent-filter></receiver>public class AppSplitViewReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction() != null &&intent.getAction().equals("actiwerks.intent.splitview")) { int peekSize = intent.getIntExtra("APP_SPLIT_SIZE", -1); // Handle the intent in the app, resize the window/layout accordingly } }}
  53. 53. ACTIONBARPLUS INTHE GITHUB
  54. 54. FUN WITHTHE LISTVIEW
  55. 55. PROBLEM ?
  56. 56. ARRAYADAPTER API NOT DESIGNEDFOR GENERICVIEWGROUP
  57. 57. interface ViewAdapterBinder<T, V> {public void bindViewToData(V view, T data);}public class ArrayViewGroupAdapter<T, V extends ViewGroup> extends ArrayAdapter<T>BIND DATATOVIEW
  58. 58. public View getView(int position, View convertView, ViewGroup parent){ // assign the view we are converting to a local variable V v = null; try { v = (V) convertView; } catch(ClassCastException ccex) {}// safe to ignore, keep null to force new instance to be created // first check to see if the view is null. if so, we have to inflate it. // to inflate it basically means to render, or show, the view. if (v == null) { v = getInstanceOfV(); } T data = getItem(position); if (data != null && binder != null) { binder.bindViewToData(v, data); } else { // signal error here prn.log("Cant bind data to view " + position); } // the view must be returned to our activity return v;}
  59. 59. private V getInstanceOfV() {ParameterizedType superClass = (ParameterizedType)getClass().getGenericSuperclass(); Class<V> type = (Class<V>) superClass.getActualTypeArguments()[1];try {return type.getDeclaredConstructor(Context.class).newInstance(getContext());} catch (Exception ex) {// Oops, no default constructorthrow new RuntimeException(ex);}}
  60. 60. public class SampleArrayAdapter extends ArrayViewGroupAdapter<SampleData, SampleListItem> { public SampleArrayAdapter(Context context) { super(context, new ArrayViewGroupAdapter.ViewAdapterBinder<SampleData, SampleListItem>() { @Override public void bindViewToData(SampleListItem view, SampleData data) { view.setTitle(data.getTitle()); view.setDetails(data.getDetails()); } }); }}
  61. 61. ATYPE-SAFE, REFACTORING FRIENDLYSOLUTION
  62. 62. ADVANTAGES FORTHE DEVELOPER ANDTHE USER
  63. 63. INSTANT LISTS WITH INTROSPECTION
  64. 64. OBJECTFORMS.COM
  65. 65. FLEXIBLE LAYOUT ALLOWS RESIZING
  66. 66. PINCHTO ZOOM GESTURE IN LISTS
  67. 67. TIME AND DATE PICKER
  68. 68. PROBLEM ?
  69. 69. UNLIKE OTHER WIDGETS,TIME & DATE PICKER NEEDS DIALOG(OR PLENTY OF SPACE)
  70. 70. SOLUTION:SPLIT EDITING INTO SPECIALIZEDTIME & DATE KEYBOARD
  71. 71. DIRECT MANIPULATION GESTURE
  72. 72. “KEYBOARD” FOR DATE SELECTION
  73. 73. NOTOUCH AT ALL
  74. 74. KINETIC GESTURES
  75. 75. SHAKE GESTURE- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{if (motion == UIEventSubtypeMotionShake) {[self showAlert];}}//When a gesture is detected (and ended) the showAlert method is called.-(IBAction)showAlert{UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"ShakeGesture Demo"message:@"Shake detected"delegate:nilcancelButtonTitle:@"OK"otherButtonTitles:nil];[alertView show];}
  76. 76. AREATHAT IS NOT GETTINGTHE LOVEIT DESERVERS
  77. 77. TIM BRAY : SENSPLORE
  78. 78. SENSOR FUSIONhttp://www.youtube.com/watch?v=C7JQ7Rpwn2k
  79. 79. SAMSUNG GESTURES
  80. 80. HELP US SHAPETHE FUTUREhttp://www.kineticgestures.org
  81. 81. TAKEWAY
  82. 82. Q & A
  83. 83. THANKYOU
  84. 84. PAVEL LAHODAPAVEL@ACTIWERKS.COM@PERPETUMDESIGN
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×