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

Post on 20-May-2020

1 views 0 download

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

Eastside Android Developers MeetupHosted by Offerup

April 28, 2016

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, tomdao@gmail.com

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

Best Practices for Designing Dashboards for Mobile Devices

Tatyana Yakushev Senior Software Engineer Tableau4/28/2016

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

Tableau helps people see and understand their data

Mobile ProductsTableau Mobile Vizable

Part 1: Best Practices for Mobile Dashboards

Part 2: Most Common Mistakes

Part 3: Q&A

Regular dashboards look like this

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

Main Characteristics of Phone Dashboards

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

Start with Your Focus

•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

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

•Highlight information that requires attention

Highlight Immediately-Actionable Data

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

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

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.

13 Common Mistakes1. Exceeding the boundaries of a single screen

This dashboard has multiple

scrollbars

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?

13 Common Mistakes3. Displaying excessive detail or precision

Time is expressed in

seconds

Measures are expressed to 10 decimal

places

13 Common Mistakes4. Choosing a deficient measure

This is not the best way to show

variance of actual revenues from the

budget

13 Common Mistakes4. Choosing a deficient measure

This is much better

13 Common Mistakes5. Choosing inappropriate media of display

Pie charts are designed to present

parts of a whole.Numbers should

add to 100%

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.

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?

13 Common Mistakes6. Introducing meaningless variety

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

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.

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

13 Common Mistakes8. Encoding quantitative data inaccurately

By failing to begin the scale at zero,

these bars inaccurately encode the quantitative

values.

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.

13 Common Mistakes

9. Arranging the data poorly

13 Common Mistakes

10. Ineffectively highlighting what’s important

13 Common Mistakes11. Misusing or overusing color

13 Common Mistakes12. Cluttering the screen with useless decoration

13 Common Mistakes13. Designing an unappealing visual display

Tatyana Yakushevtyakushev@tableau.com

Copyright © MetaBrite, Inc.

Intro to Android Testing

Yenchi Linyenchi@gmail.com

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.

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.

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.

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.

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.

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

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.

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

Copyright © MetaBrite, Inc.

Now You Need to Implement a New Function

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

Copyright © MetaBrite, Inc.

Q & A?

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

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

Thank you!

Yenchi Linyenchi@gmail.comGitHub: https://github.com/xcatgTwitter @xcatghttps://plus.google.com/+YenchiLin

http://www.metabrite.com/careers

RxJava/RxAndroid

Wilson Burhan

Terms in RxJava

ObservableObservable.from(someOperations())

.subscribeOn(Schedulers. io())

.observeOn(AndroidSchedulers. mainThread())

.subscribe(getObserver())

Scheduler

Observer

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

Terms in RxJava

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

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

OperationsCombine Latest

Debounce

FlatMap

Zip

Combine Latest

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

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

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

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

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

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'

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

RxJava/RxAndroid

google.com/+WilsonBurhanwilson@offerupnow.com

●●●

○○○

●●