Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside...

66
Eastside Android Developers Meetup Hosted by Offerup April 28, 2016

Transcript of Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside...

Page 1: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Eastside Android Developers MeetupHosted by Offerup

April 28, 2016

Page 2: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Lightning Talk Speakers● Tatyana Yakushev, Tableau - Mobile Dashboard Design● Wilson Burhan, OfferUp - RxJava/RxAndroid● Yenchi Lin, MetaBrite - Intro to Android Testing● Delong Fu, MSR - Microsoft Cognitive Services

Meetup hosts● Margaret Maynard-Reid, @margaretmz● Tom Dao, [email protected]

http://www.meetup.com/Eastside-Android-Meetup-Group/events/230323252/

Page 3: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Best Practices for Designing Dashboards for Mobile Devices

Tatyana Yakushev Senior Software Engineer Tableau4/28/2016

Page 4: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Public company with offices in Seattle, Kirkland, Palo Alto, Austin and Vancouver

Tableau helps people see and understand their data

Page 5: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Mobile ProductsTableau Mobile Vizable

Page 6: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Part 1: Best Practices for Mobile Dashboards

Part 2: Most Common Mistakes

Part 3: Q&A

Page 7: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Regular dashboards look like this

Page 8: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

•Small screen size•Used on the go•Used for short periods of time

Main Characteristics of Phone Dashboards

Page 9: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

• What information do you need to present to the users?

Start with Your Focus

Page 10: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

•Find ways to personalized the information to each person instead of asking users to filter it themselves

Customize the Data for Each Person

•People use phones to monitor changes throughout the day

Use Real-Time Data

Page 11: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

•Current quota performance is likely to be more useful than historical sales data

•Highlight information that requires attention

Highlight Immediately-Actionable Data

Page 12: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Opt for Simple Views

• Simple views are more useful than complicated views and sophisticated dashboards

• Summary• KPIs

Go for• Line charts• Bar charts• Area charts• Highlight tables• Simplified field maps• Dot maps

Avoid• Scatter plots• Line charts with many series• Complex tables

Page 13: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes

1. Exceeding the boundaries of a single screen

Information that appears on dashboards is often fragmented in one of two ways:

2. Separated into discrete screens to which one must navigate

3. Separated into different instances of a single screen that are accessed through some form of interaction

Page 14: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes1. Exceeding the boundaries of a single screen

This dashboard fragments the data

in a way that undermines the

viewer’s ability to see meaningful

relationships.

Page 15: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes1. Exceeding the boundaries of a single screen

This dashboard has multiple

scrollbars

Page 16: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes2. Supplying inadequate context for the data

or

Both of the views are missing useful context1. How bad or good are these numbers?2. Are we on track?3. Are we doing better or worse than in the

past?

Page 17: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes3. Displaying excessive detail or precision

Time is expressed in

seconds

Measures are expressed to 10 decimal

places

Page 18: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes4. Choosing a deficient measure

This is not the best way to show

variance of actual revenues from the

budget

Page 19: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes4. Choosing a deficient measure

This is much better

Page 20: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes5. Choosing inappropriate media of display

Pie charts are designed to present

parts of a whole.Numbers should

add to 100%

Page 21: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes5. Choosing inappropriate media of display

Even when used correctly, pie charts are difficult to interpret accurately.Visualization on the right is much better.

Page 22: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes5. Choosing inappropriate media of displayOther types of graphs can be equally ineffective

Circles are not a good way to

encode quantities.

Should I look at the diameter or

area?

Page 23: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes6. Introducing meaningless variety

The bars on the left vary in color for no meaningful reason.

Page 24: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes7. Using poorly designed display media

1. A legend was used to label and assign values to the slices of the pie. This forces our eyes to bounce back and forth between the graph and the legend to glean meaning, which is a waste of time and effort when the slices could have been labeled directly.

2. The order of the slices and the corresponding labels appears random. Ordering them by size would have provided useful information that could have been assimilated instantly.

3. The bright colors of the pie slices produce sensory overkill. Bright colors ought to be reserved for specific data that should stand out from the rest.

Page 25: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes7. Using poorly designed display media

1. 3-D effect makes values encoded by the bars harder to interpret.

2. Perspective makes it more difficult to compare numbers

Page 26: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes8. Encoding quantitative data inaccurately

By failing to begin the scale at zero,

these bars inaccurately encode the quantitative

values.

Page 27: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes9. Arranging the data poorlyThe most important data ought to be prominent.• Data that require immediate attention ought to stand out.• Data that should be compared ought to be arranged and visually designed to encourage comparisons.

Page 28: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes

9. Arranging the data poorly

Page 29: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes

10. Ineffectively highlighting what’s important

Page 30: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes11. Misusing or overusing color

Page 31: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes12. Cluttering the screen with useless decoration

Page 32: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

13 Common Mistakes13. Designing an unappealing visual display

Page 33: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Tatyana [email protected]

Page 34: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

Intro to Android Testing

Yenchi [email protected]

Page 35: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

We write Android apps, but...

We don’t write tests because• Tight schedule• Tests are hard to write• Android Tests are even harder to write• Other reasons

Therefore, we don’t write tests.

But, you are a good developer who want to be even better. Writing tests is one step toward being a better developer.

Page 36: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

You have an Android App, you want to add a test

Android Studio helps you by placing these directories automatically in a new project:• androidTest

• Instrumentation tests go in here• test

• Java tests go in hereIf your app doesn’t have these, create them.

Page 37: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

JUnit Tests v.s. Instrumentation Tests

Regular JUnit tests can run on your machine’s JVM; Instrumentation tests run on your phone or emulator where Android Framework is.

If the thing you want to test has no Android dependency, they can be a regular JUnit test. If your class uses Android framework code, like a `Context`, you usually will want to use Instrumentation Tests.

Page 38: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

You have an Android App, you want to add a test

Add necessary dependency in your build.gradle file. For example: Java unit tests, you want to include JUnit 4 testCompile 'junit:junit:4.12'

For instrumentation tests, you want to include at least the JUnitRunner androidTestCompile 'com.android.support.test:runner:0.5'

And add the following to your defaultConfig{} testInstrumentationRunner "android.support.test.runner.

AndroidJUnitRunner"

See [ATSL] for detailed setup for instrumentation tests.

Page 39: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

An Android UI Test Example

@RunWith(AndroidJUnit4.class)

public class MainActivityTest {

@Rule

public TestRule mTestRule =

new ActivityTestRule<MainActivity>(MainActivity.class);

@Test

public void testMyUITest() throws Exception {

//...

}

}

It’s just another JUnit4 test suite.

Page 40: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

To Run the Test

Right click on your Test class in project view, or right click on the Test class name in the editor, and from the context menu, select Run ‘Test’ with the “Play” icon.

In some cases, you might see Run with JUnit which will usually result in strange run results.

You can hit to run the same test again

Page 41: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

A Simple Test for a Simple App

Say you want to check “Hello World” is indeed on screen. This test is written using Espresso.@Test

public void testMyUITest() throws Exception {

onView(withText(R.string.hello)).check(matches(isDisplayed()));

}

Where R.string.hello is “Hello World!”

For details on Espresso, see [ATSL] website for samples and cheatsheet.

Page 42: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

Now You Need to Implement a New Feature

New feature! Tapping on the fab changes the hello world text!Let’s change the test@Test

public void testMyUITest() throws Exception {

// ensure hello world text is on screen

onView(withId(R.id.text)).check(matches(withText(R.string.hello)));

// tap on the fab button

onView(withId(R.id.fab)).check(matches(isDisplayed())).perform(click());

// make sure text where hello world was displayed now shows "modified text"

onView(withId(R.id.text)).check(matches(withText("modified text")));

}

And of course the test fails

Page 43: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

Now You Need to Implement a New Function

Page 44: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

Is this helpful to me as a Developer?

Having automated tests gives you:• Faster turnaround time for bugs• Catch if code changes break your feature• Might be faster to iterate during development

Page 45: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.

Q & A?

Links & References[ATSL] https://google.github.io/android-testing-support-library/

Page 46: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Copyright © MetaBrite, Inc.Copyright © MetaBrite, Inc.

Thank you!

Yenchi [email protected]: https://github.com/xcatgTwitter @xcatghttps://plus.google.com/+YenchiLin

http://www.metabrite.com/careers

Page 47: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

RxJava/RxAndroid

Wilson Burhan

Page 48: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Terms in RxJava

ObservableObservable.from(someOperations())

.subscribeOn(Schedulers. io())

.observeOn(AndroidSchedulers. mainThread())

.subscribe(getObserver())

Scheduler

Observer

Subscription- onCompleted()- onError(Throwable)- onNext(result)

Page 49: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Terms in RxJava

interface Action1<T> { void call(T t);}

interface Func1<T> { R call(T t);}

Page 50: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

OperationsCombine Latest

Debounce

FlatMap

Zip

Page 51: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Combine Latest

nameObservable = RxTextView.textChanges(nameEditText);emailObservable = RxTextView.textChanges(emailEditText);passwordObservable = RxTextView.textChanges(passwordEditText);

Page 52: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Observable.combineLatest(nameObservable,emailObservable,passwordObservable, new Func3<CharSequence, CharSequence, CharSequence, Boolean>() {

@Override public Boolean call(CharSequence nameInput, CharSequence emailInput, CharSequence passwordInput) { // insert form validation logic here return isNameValid & isEmailValid & isPasswordValid; }}) .subscribe(new Observer<Boolean>() { @Override public void onCompleted() { }

@Override public void onError(Throwable e) { }

@Override public void onNext(Boolean formValid) { if (formValid) { signupBtn.setEnabled(true); } else { signupBtn.setEnabled(false); } }});

Combine Latest

Page 53: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

DebounceinputTextObservable .debounce(400, TimeUnit.MILLISECONDS, Schedulers.computation())

.observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<TextViewTextChangeEvent>() { @Override public void onCompleted() { }

@Override public void onError(Throwable e) { }

@Override public void onNext(TextViewTextChangeEvent textViewTextChangeEvent) { printToScreen(String.format("Inputted text is: %s", textViewTextChangeEvent.text().toString())); } });

Page 54: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

FlatMapObservable.just(userIdInput.getText().toString()) .flatMap(new Func1<String, Observable<UserResponse>>() { @Override public Observable<UserResponse> call(String s) { return userService.getUser(s); // Retrofit call } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<UserResponse>() { @Override public void onCompleted() { }

@Override public void onError(Throwable e) { }

@Override public void onNext(UserResponse userResponse) { updateUI(userResponse); }});

String

Page 55: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

rx.Observable .zip(userService.getUser("1"), userService.getUserPost("1"), new Func2<UserResponse, PostResponse, UserAndPostResponse>() { @Override public UserAndPostResponse call(UserResponse userResponse, PostResponse postResponses) { return new UserAndPostResponse(userResponse, postResponses); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<UserAndPostResponse>() { @Override public void onCompleted() { }

@Override public void onError(Throwable e) { }

@Override public void onNext(UserAndPostResponse userAndPostResponse) { updateUI(userAndPostResponse); }});

Zip

Page 56: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Gradle

RxJavacompile 'io.reactivex:rxjava:1.0.14'

RxAndroidcompile 'io.reactivex:rxandroid:1.0.1'

RxBinding (optional)compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'

Page 57: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

RxWTF?ReactiveX homepage

http://reactive.io/

Source codehttps://github.com/reactivex/rxjava

RxMarbleshttp://rxmarbles.com/

“Grokking RxJava” blog series by Dan Lewhttp://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

“Advance RxJava” blog series by David Karnokhttp://akarnokd.blogspot.hu/

RXAndroid samples https://github.com/wburhan2/rxandroid-sample

Page 58: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

RxJava/RxAndroid

google.com/[email protected]

Page 59: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed
Page 60: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed
Page 62: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

●●●

○○○

Page 63: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

Page 64: Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside Android Lightning... · 2016-05-04 · 13 Common Mistakes 7. Using poorly designed

●●