84
IMPROVING ANDROID EXPERIENCE FOR BOTH USERS AND DEVELOPERS droidcon Berlin 2013, Pavel Lahoda, Actiwerks Ltd.

Improving android experience for both users and developers

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Improving android experience for both users and developers

IMPROVING ANDROID EXPERIENCE FOR BOTH USERS AND DEVELOPERS

droidcon Berlin 2013, Pavel Lahoda, Actiwerks Ltd.

Page 2: Improving android experience for both users and developers

LET’S HAVE A LITTLE WARMUP

Page 3: Improving android experience for both users and developers

ANDROID.UTIL.LOG

Page 4: Improving android experience for both users and developers

HOW MANY TIMES YOU’VE TYPED THIS ?

Page 5: Improving android experience for both users and developers

prn.log("Index=" + i);

HOW ABOUT THIS ?

Page 6: Improving android experience for both users and developers

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 ?

Page 7: Improving android experience for both users and developers

GITHUB LINK

Page 8: Improving android experience for both users and developers

WHERE IS THE UX ?

Page 9: Improving android experience for both users and developers

HAVE TIME TO WORK ON AWESOME STUFF !

Page 10: Improving android experience for both users and developers

IMPORTANCE OF HAVING YOUR VIEW FLEXIBLE

Page 11: Improving android experience for both users and developers

ANDROID AND WEB COMMON STUFFUNLIMITED AMOUNT OF DISPLAY SIZES

Page 12: Improving android experience for both users and developers

WEB TRENDS: RESPONSIVE DESIGN

Page 13: Improving android experience for both users and developers

ANDROID TRENDS: LOTS OF WORK

Page 14: Improving android experience for both users and developers

CURRENT ANDROID LAYOUTS ARE NOT FLEXIBLE ENOUGH

Page 15: Improving android experience for both users and developers

ALTERNATIVE:USE PURE JAVA VIEWGROUP

Page 16: Improving android experience for both users and developers

@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

}

Page 17: Improving android experience for both users and developers

ONMEASURE() - PLACE FOR YOUR LOGIC

Page 18: Improving android experience for both users and developers

NO NEED TO REBIND COMPONENTS OR CALL SLOW LAYOUT INFLATE CODE

Page 19: Improving android experience for both users and developers

WORKS GREAT FOR ORIENTATION CHANGES

Page 20: Improving android experience for both users and developers

BBC NEWS FOR TABLETS EXAMPLE

Page 21: Improving android experience for both users and developers

INSPIRATION:WEB RESPONSIVE LAYOUT

Page 22: Improving android experience for both users and developers

DEAL WITH MANY DIFFERENT SCREEN SIZES

Page 23: Improving android experience for both users and developers

STANDOUT - FLOATING WINDOWS

Page 24: Improving android experience for both users and developers

ACTION BAR

Page 25: Improving android experience for both users and developers

ONE OF WORST EXAMPLES OF API DESIGN

Page 26: Improving android experience for both users and developers

ACTIONBAR IS NOT A DESCENDANT OF A VIEW

Page 27: Improving android experience for both users and developers

BLOG.PERPETUMDESIGN.COM/2011/08/STRANGE-CASE-OF-DR-ACTION-AND-

MR-BAR.HTML

Page 28: Improving android experience for both users and developers

ACTIONBARSHERLOCK

Page 29: Improving android experience for both users and developers

ACTION BAR PLUS

Page 30: Improving android experience for both users and developers

PROBLEM ?

Page 31: Improving android experience for both users and developers

AB OCCUPIES ~10% OF SCREEN SPACE

Page 32: Improving android experience for both users and developers

FUNCTIONALITY OFTEN REDUCED TO BRANDING

Page 33: Improving android experience for both users and developers

FLY-OUT MENU: A FACEBOOK SOLUTION

Page 34: Improving android experience for both users and developers

NOT CONSISTENT WITH THE REST OF ACTIONBAR FUNCTIONALITY

Page 35: Improving android experience for both users and developers

ACTIONBAR PARTS

Page 36: Improving android experience for both users and developers

ACTIONBAR BEHAVIOR

Touch here showsa menu with options

Touch here moves up in hierarchy

Touch here performs action

Touch here show a menu with options

Any extension should stay consistent with this

Page 37: Improving android experience for both users and developers

DON’T CONFUSE YOUR USERS

Page 38: Improving android experience for both users and developers

OWN APPS’D USE SOME UX FACELIFT

Page 39: Improving android experience for both users and developers

STILL WANT MORE FROM THE ACTIONBAR AREA ?

Page 40: Improving android experience for both users and developers

ACTION BAR PLUSCUSTOM ACTIONBAR IMPLEMENTATION

Page 41: Improving android experience for both users and developers

EMBRACE EXTRA DIMENSION

Page 42: Improving android experience for both users and developers

TWO TYPES OF NAVIGATION

Page 43: Improving android experience for both users and developers

MAKE SURE THERE IS DEAD AREA TO SEPARATE FROM NOTIFICATION BAR

GESTURE

Page 44: Improving android experience for both users and developers

USE MIDDLE AS BONUS CONTENT

Page 45: Improving android experience for both users and developers

SUCH AS STUFF OUTSIDE THE APP

Page 46: Improving android experience for both users and developers

2D JUST ON OVERFLOWACTIONS ARE EITHER TOUCH

OR SWIPE DOWN

Page 47: Improving android experience for both users and developers

ACCESS TO HELP ON ACTIONS

Page 48: Improving android experience for both users and developers

EMBRACE MULTITOUCH

Page 49: Improving android experience for both users and developers

EASY SPLIT VIEW FEATURE

Page 50: Improving android experience for both users and developers

BROADCAST THE AVAILABLE SCREEN

actiwerks.intent.splitviewDESCRIPTION OF THE INTENT APPEARS SOON ON THE OPENINTENTS.ORG

Page 51: Improving android experience for both users and developers

BROADCAST DETAILS

private Intent splitIntent;

splitIntent = new Intent();splitIntent.setAction("actiwerks.intent.splitview");

splitIntent.removeExtra("APP_SPLIT_SIZE");splitIntent.putExtra("APP_SPLIT_SIZE", windowVerticalOffset);getContext().sendBroadcast(splitIntent);

Page 52: Improving android experience for both users and developers

RECEIVE THE 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 } }

}

Page 53: Improving android experience for both users and developers

ACTIONBARPLUS IN THE GITHUB

Page 54: Improving android experience for both users and developers

FUN WITH THE LIST VIEW

Page 55: Improving android experience for both users and developers

PROBLEM ?

Page 56: Improving android experience for both users and developers

ARRAYADAPTER API NOT DESIGNEDFOR GENERIC VIEWGROUP

Page 57: Improving android experience for both users and developers

interface ViewAdapterBinder<T, V> {public void bindViewToData(V view, T data);

}

public class ArrayViewGroupAdapter<T, V extends ViewGroup> extends ArrayAdapter<T>

BIND DATA TO VIEW

Page 58: Improving android experience for both users and developers

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("Can't bind data to view " + position); } // the view must be returned to our activity return v;

}

Page 59: Improving android experience for both users and developers

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);

}

}

Page 60: Improving android experience for both users and developers

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()); } }); }}

Page 61: Improving android experience for both users and developers

A TYPE-SAFE, REFACTORING FRIENDLY SOLUTION

Page 62: Improving android experience for both users and developers

ADVANTAGES FOR THE DEVELOPER AND THE USER

Page 63: Improving android experience for both users and developers

INSTANT LISTS WITH INTROSPECTION

Page 64: Improving android experience for both users and developers

OBJECTFORMS.COM

Page 65: Improving android experience for both users and developers

FLEXIBLE LAYOUT ALLOWS RESIZING

Page 66: Improving android experience for both users and developers

PINCH TO ZOOM GESTURE IN LISTS

Page 67: Improving android experience for both users and developers

TIME AND DATE PICKER

Page 68: Improving android experience for both users and developers

PROBLEM ?

Page 69: Improving android experience for both users and developers

UNLIKE OTHER WIDGETS, TIME & DATE PICKER NEEDS DIALOG

(OR PLENTY OF SPACE)

Page 70: Improving android experience for both users and developers

SOLUTION:SPLIT EDITING INTO SPECIALIZED

TIME & DATE KEYBOARD

Page 71: Improving android experience for both users and developers

DIRECT MANIPULATION GESTURE

Page 72: Improving android experience for both users and developers

“KEYBOARD” FOR DATE SELECTION

Page 73: Improving android experience for both users and developers

NO TOUCH AT ALL

Page 74: Improving android experience for both users and developers

KINETIC GESTURES

Page 75: Improving android experience for both users and developers

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:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show];}

Page 76: Improving android experience for both users and developers

AREA THAT IS NOT GETTING THE LOVE IT DESERVERS

Page 77: Improving android experience for both users and developers

TIM BRAY : SENSPLORE

Page 79: Improving android experience for both users and developers

SAMSUNG GESTURES

Page 80: Improving android experience for both users and developers

HELP US SHAPE THE FUTURE

http://www.kineticgestures.org

Page 81: Improving android experience for both users and developers

TAKEWAY

Page 82: Improving android experience for both users and developers

Q & A

Page 83: Improving android experience for both users and developers

THANK YOU