Eastside Android Developers Meetup Hosted by Offerup April 28, …files.meetup.com/17404842/Eastside...
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, [email protected]
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 [email protected]
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 [email protected]: 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/[email protected]
●
○
●
●●