Improving android experience for both users and developers

376 views

Published on

Android UI and User Experience has changed dramatically in the recent version(s) and while users generally enjoy the new features, there are still several areas that are left to application-level-DIY-patterns. For developers, this is double challenge, they want to provide users with the bleeding edge UI patterns and at the same time, they have to deal with evolving API, that sometimes changes dramatically.
Presentation covers the gotchas developer might face dealing with ever-moving Android API, and how to utilize Java language and the tools it have to make the experience for developer more pleasant. Typical trends in the API will get analyzed and divided into several areas or "patterns", discussing typical scenarios how these components are designed and implemented.
This talk will propose several such UI patterns, that will compete to become "de facto" standards and details on the implementation, including possible impact on existing API as we have both end users and developers in mind.

The list of patterns/areas discussed in the talk include following :

ActionBar
ListView
TimePicker
KineticGestureComponent

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
376
On SlideShare
0
From Embeds
0
Number of Embeds
45
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Improving android experience for both users and developers

  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

×