| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent eeb850d commit cd202c8
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,14 +15,6 @@ The long operation is simulated by a blocking Thread.sleep call (since this is d | |||
| 15 | 15 | ||
| 16 | 16 | To really see this example shine. Hit the button multiple times and see how the button click (which is a ui operation) is never blocked because the long operation only runs in the background. | |
| 17 | 17 | ||
| 18 | - ### Instant/Auto searching (subject + debounce) | ||
| 19 | - | ||
| 20 | - This is a demo of how events can be swallowed in a way that only the last one is respected. A typical example of this is instant search result boxes. As you type the word "Bruce Lee", you don't want to execute searches for B, Br, Bru, Bruce, Bruce , Bruce L ... etc. But rather intelligently wait for a couple of moments, make sure the user has finished typing the whole word, and then shoot out a single call for "Bruce Lee". | ||
| 21 | - | ||
| 22 | - As you type in the input box, it will not shoot out log messages at every single input character change, but rather only pick the lastly emitted event (i.e. input) and log that. | ||
| 23 | - | ||
| 24 | - This is the debounce/throttleWithTimeout method in RxJava. | ||
| 25 | - | ||
| 26 | 18 | ### Accumulate calls (buffer) | |
| 27 | 19 | ||
| 28 | 20 | This is a demo of how events can be accumulated using the "buffer" operation. | |
@@ -31,45 +23,54 @@ A button is provided and we accumulate the number of clicks on that button, over | |||
| 31 | 23 | ||
| 32 | 24 | If you hit the button once. you'll get message saying the button was hit once. If you hit it 5 times continuosly within a span of 2 seconds, then you get a single log, saying you hit that button 5 times (vs 5 individual logs saying "Button hit once"). | |
| 33 | 25 | ||
| 34 | - Two implementations: | ||
| 26 | + Two possible implementations: | ||
| 35 | 27 | ||
| 36 | - 2a. Using a traditional observable - but encompassing the OnClick within the observable | ||
| 28 | + 2a. Using a traditional observable - but encompassing the OnClick within the observable (as demoed here) | ||
| 37 | 29 | 2b. Using PublishSubject and sending single clicks to the Observable, which in-turn then sends it to the Observer | |
| 38 | 30 | ||
| 31 | + ### Instant/Auto searching (subject + debounce) | ||
| 32 | + | ||
| 33 | + This is a demo of how events can be swallowed in a way that only the last one is respected. A typical example of this is instant search result boxes. As you type the word "Bruce Lee", you don't want to execute searches for B, Br, Bru, Bruce, Bruce , Bruce L ... etc. But rather intelligently wait for a couple of moments, make sure the user has finished typing the whole word, and then shoot out a single call for "Bruce Lee". | ||
| 34 | + | ||
| 35 | + As you type in the input box, it will not shoot out log messages at every single input character change, but rather only pick the lastly emitted event (i.e. input) and log that. | ||
| 36 | + | ||
| 37 | + This is the debounce/throttleWithTimeout method in RxJava. | ||
| 38 | + | ||
| 39 | 39 | ### Retrofit and RxJava (zip, flatmap) | |
| 40 | 40 | ||
| 41 | - [Retrofit from Square](http://square.github.io/retrofit/) is an another amazing library that helps with easy networking (even if you haven't made the jump to RxJava just yet, you really should check it out). It works even better with RxJava and these are examples taken straight up from the android demigod developer Jake Wharton's talk at Netflix. You can [watch the talk](https://www.youtube.com/watch?v=aEuNBk1b5OE#t=2480) at this link. Incidentally, my motiviation to use RxJava was from attending this talk at Netflix. | ||
| 41 | + [Retrofit from Square](http://square.github.io/retrofit/) is an amazing library that helps with easy networking (even if you haven't made the jump to RxJava just yet, you really should check it out). It works even better with RxJava and these are examples hitting the github api, taken straight up from the android demigod-developer Jake Wharton's talk at Netflix. You can [watch the talk](https://www.youtube.com/watch?v=aEuNBk1b5OE#t=2480) at this link. Incidentally, my motiviation to use RxJava was from attending this talk at Netflix. | ||
| 42 | 42 | ||
| 43 | - Since it was a presentation, Jake only put up the most important code snippets in [his slides](https://speakerdeck.com/jakewharton/2014-1). Also he uses Java 8 in them, so I flushed those examples out in ~~good~~ old Java 6. | ||
| 43 | + Since it was a presentation, Jake only put up the most important code snippets in [his slides](https://speakerdeck.com/jakewharton/2014-1). Also he uses Java 8 in them, so I flushed those examples out in ~~good~~ old Java 6. (Note: you're most likely to hit the github api quota pretty fast so send in an oauth-token as a parameter if you want to keep running these examples often). | ||
| 44 | 44 | ||
| 45 | - ## Work in Progress: | ||
| 45 | + ### Orchestrating Observables. Make parallel network calls, then combine the result into a single data point (flatmap + zip) | ||
| 46 | 46 | ||
| 47 | - ### First retrieve from cached data, then make a network call if you can't find your data (concat) (wip) | ||
| 47 | + The below ascii diagram expresses the intention of our next example with panache. f1,f2,3,f4,f5 are essentially network calls that when made, give back a result that' needed for a future calculation. | ||
| 48 | 48 | ||
| 49 | - [Courtesy: gist](https://gist.github.com/adelnizamutdinov/7483969) | ||
| 50 | 49 | ||
| 51 | - ### Make two parallel network calls, then combine the result into a single data point (zip) (wip) | ||
| 50 | + (flatmap) | ||
| 51 | + f1 ___________________ f3 _______ | ||
| 52 | + (flatmap) | (zip) | ||
| 53 | + f2 ___________________ f4 _______| ___________ final output | ||
| 54 | + \ | | ||
| 55 | + \____________ f5 _______| | ||
| 52 | 56 | ||
| 53 | - [Courtesy: gist](https://gist.github.com/adelnizamutdinov/7483969) | ||
| 54 | - http://www.programmableweb.com/category/all/apis?order=field_popularity | ||
| 57 | + The code for this example has already been written by one Mr.skehlet in the interwebs. Head over to [the gist](https://gist.github.com/skehlet/9418379) for the code. It's written in pure Java (6) so it's pretty comprehensible if you've understood the previous examples. I'll flush it out here again when time permits, and I find a lack of other compelling examples. | ||
| 55 | 58 | ||
| 56 | - ### Orchestrating Observables (flatmap + zip) (wip) | ||
| 59 | + ### Double binding with TextViews () | ||
| 57 | 60 | ||
| 58 | - If actions A and B depend on action X running; and action C depends on action Y running. What if you want to combine the result of all those calls and have a single output? | ||
| 59 | 61 | ||
| 60 | - ____________ A ________________ | ||
| 61 | - (flatmap) / | (zip all 3) | ||
| 62 | - X ------------/_____________ B ________________| ----------- > Ouput | ||
| 63 | - | | ||
| 64 | - Y ------------------------- C ________________| | ||
| 65 | 62 | ||
| 66 | - ### Pagination (zip) (wip) | ||
| 67 | 63 | ||
| 68 | - a. Simple pagination | ||
| 69 | - b. Optimized pagination | ||
| 64 | + ## Work in Progress: | ||
| 65 | + | ||
| 66 | + ### First retrieve from cached data, if no cache found make a network call if you can't find your data (concat) (wip) | ||
| 67 | + [Courtesy: gist](https://gist.github.com/adelnizamutdinov/7483969) | ||
| 70 | 68 | ||
| 69 | + ### Pagination (wip) | ||
| 71 | 70 | ||
| 71 | + a. Simple pagination | ||
| 72 | + b. Optimized pagination | ||
| 72 | 73 | ||
| 73 | - ### Replacing your event Bus (wip) | ||
| 74 | + ### Event Bus with RxJAva (wip) | ||
| 74 | 75 | ||
| 75 | 76 | http://stackoverflow.com/questions/19266834/rxjava-and-random-sporadic-events-on-android | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,76 @@ | |||
| 1 | + package com.morihacky.android.rxjava; | ||
| 2 | + | ||
| 3 | + import android.content.Context; | ||
| 4 | + import android.os.Bundle; | ||
| 5 | + import android.support.annotation.Nullable; | ||
| 6 | + import android.support.v4.app.Fragment; | ||
| 7 | + import android.view.LayoutInflater; | ||
| 8 | + import android.view.View; | ||
| 9 | + import android.view.ViewGroup; | ||
| 10 | + import android.view.inputmethod.InputMethodManager; | ||
| 11 | + import android.widget.EditText; | ||
| 12 | + import android.widget.TextView; | ||
| 13 | + import butterknife.ButterKnife; | ||
| 14 | + import butterknife.InjectView; | ||
| 15 | + import butterknife.OnTextChanged; | ||
| 16 | + import com.google.common.base.Strings; | ||
| 17 | + import com.morihacky.android.rxjava.app.R; | ||
| 18 | + import rx.Subscription; | ||
| 19 | + import rx.functions.Action1; | ||
| 20 | + import rx.subjects.PublishSubject; | ||
| 21 | + | ||
| 22 | + public class DoubleBindingTextViewFragment | ||
| 23 | + extends Fragment { | ||
| 24 | + | ||
| 25 | + @InjectView(R.id.double_binding_num1) EditText _number1; | ||
| 26 | + @InjectView(R.id.double_binding_num2) EditText _number2; | ||
| 27 | + @InjectView(R.id.double_binding_result) TextView _result; | ||
| 28 | + | ||
| 29 | + Subscription _subscription; | ||
| 30 | + PublishSubject<Float> _resultEmitterSubject; | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + public View onCreateView(LayoutInflater inflater, | ||
| 34 | + @Nullable ViewGroup container, | ||
| 35 | + @Nullable Bundle savedInstanceState) { | ||
| 36 | + View layout = inflater.inflate(R.layout.fragment_double_binding_textview, container, false); | ||
| 37 | + ButterKnife.inject(this, layout); | ||
| 38 | + | ||
| 39 | + _resultEmitterSubject = PublishSubject.create(); | ||
| 40 | + _subscription = _resultEmitterSubject.asObservable().subscribe(new Action1<Float>() { | ||
| 41 | + @Override | ||
| 42 | + public void call(Float aFloat) { | ||
| 43 | + _result.setText(String.valueOf(aFloat)); | ||
| 44 | + } | ||
| 45 | + }); | ||
| 46 | + | ||
| 47 | + onNumberChanged(); | ||
| 48 | + _number2.requestFocus(); | ||
| 49 | + | ||
| 50 | + return layout; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @OnTextChanged({ R.id.double_binding_num1, R.id.double_binding_num2 }) | ||
| 54 | + public void onNumberChanged() { | ||
| 55 | + float num1 = 0; | ||
| 56 | + float num2 = 0; | ||
| 57 | + | ||
| 58 | + if (!Strings.isNullOrEmpty(_number1.getText().toString())) { | ||
| 59 | + num1 = Float.parseFloat(_number1.getText().toString()); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + if (!Strings.isNullOrEmpty(_number2.getText().toString())) { | ||
| 63 | + num2 = Float.parseFloat(_number2.getText().toString()); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + _resultEmitterSubject.onNext(num1 + num2); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + @Override | ||
| 70 | + public void onDestroyView() { | ||
| 71 | + super.onDestroyView(); | ||
| 72 | + if (_subscription != null) { | ||
| 73 | + _subscription.unsubscribe(); | ||
| 74 | + } | ||
| 75 | + } | ||
| 76 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,7 +17,6 @@ protected void onCreate(Bundle savedInstanceState) { | |||
| 17 | 17 | ||
| 18 | 18 | getSupportFragmentManager().beginTransaction().addToBackStack(this.toString()) | |
| 19 | 19 | .replace(R.id.activity_main, new MainFragment(), this.toString()) | |
| 20 | - //.replace(R.id.activity_main, new SubjectDebounceSearchEmitterFragment(), this.toString()) | ||
| 21 | 20 | .commit(); | |
| 22 | 21 | } | |
| 23 | 22 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -58,6 +58,15 @@ public void demoRetrofitCalls() { | |||
| 58 | 58 | .commit(); | |
| 59 | 59 | } | |
| 60 | 60 | ||
| 61 | + @OnClick(R.id.btn_demo_double_binding_textview) | ||
| 62 | + public void demoDoubleBindingWithPublishSubject() { | ||
| 63 | + getActivity().getSupportFragmentManager() | ||
| 64 | + .beginTransaction() | ||
| 65 | + .addToBackStack(this.toString()) | ||
| 66 | + .replace(R.id.activity_main, new DoubleBindingTextViewFragment(), this.toString()) | ||
| 67 | + .commit(); | ||
| 68 | + } | ||
| 69 | + | ||
| 61 | 70 | //@OnClick(R.id.btn_demo_subject_timeout) | |
| 62 | 71 | public void demoTimeout() { | |
| 63 | 72 | getActivity().getSupportFragmentManager() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,56 @@ | |||
| 1 | + <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | + | ||
| 3 | + <LinearLayout | ||
| 4 | + android:orientation="vertical" | ||
| 5 | + android:layout_height="match_parent" | ||
| 6 | + android:layout_width="match_parent" | ||
| 7 | + xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 8 | + | ||
| 9 | + <TextView | ||
| 10 | + android:layout_height="wrap_content" | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:padding="10dp" | ||
| 13 | + android:gravity="center" | ||
| 14 | + android:text="@string/msg_demo_doublebinding"/> | ||
| 15 | + | ||
| 16 | + <LinearLayout | ||
| 17 | + android:layout_height="wrap_content" | ||
| 18 | + android:layout_width="match_parent" | ||
| 19 | + android:layout_marginTop="10dp"> | ||
| 20 | + | ||
| 21 | + <EditText | ||
| 22 | + android:id="@+id/double_binding_num1" | ||
| 23 | + android:layout_weight="1" | ||
| 24 | + android:layout_height="50dp" | ||
| 25 | + android:layout_width="0dp" | ||
| 26 | + android:gravity="center" | ||
| 27 | + android:inputType="numberDecimal" | ||
| 28 | + android:text="100"/> | ||
| 29 | + | ||
| 30 | + <TextView | ||
| 31 | + android:layout_weight="1" | ||
| 32 | + android:layout_height="50dp" | ||
| 33 | + android:layout_width="0dp" | ||
| 34 | + android:gravity="center" | ||
| 35 | + android:text="+"/> | ||
| 36 | + | ||
| 37 | + <EditText | ||
| 38 | + android:id="@+id/double_binding_num2" | ||
| 39 | + android:layout_weight="1" | ||
| 40 | + android:layout_height="50dp" | ||
| 41 | + android:layout_width="0dp" | ||
| 42 | + android:inputType="numberDecimal" | ||
| 43 | + android:gravity="center" | ||
| 44 | + android:text="8"/> | ||
| 45 | + </LinearLayout> | ||
| 46 | + | ||
| 47 | + <TextView | ||
| 48 | + android:id="@+id/double_binding_result" | ||
| 49 | + android:layout_height="wrap_content" | ||
| 50 | + android:layout_width="match_parent" | ||
| 51 | + android:layout_marginTop="10dp" | ||
| 52 | + android:gravity="center" | ||
| 53 | + android:textSize="45sp" | ||
| 54 | + android:text="0"/> | ||
| 55 | + | ||
| 56 | + </LinearLayout> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,5 +38,11 @@ | |||
| 38 | 38 | android:layout_height="wrap_content" | |
| 39 | 39 | android:layout_width="match_parent" | |
| 40 | 40 | android:text="@string/btn_demo_retrofit"/> | |
| 41 | + | ||
| 42 | + <Button | ||
| 43 | + android:id="@+id/btn_demo_double_binding_textview" | ||
| 44 | + android:layout_height="wrap_content" | ||
| 45 | + android:layout_width="match_parent" | ||
| 46 | + android:text="@string/btn_demo_double_binding_textview"/> | ||
| 41 | 47 | </LinearLayout> | |
| 42 | 48 | </ScrollView> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,4 +16,6 @@ | |||
| 16 | 16 | <string name="btn_demo_subject_debounce">search text listener(subject debouncing)</string> | |
| 17 | 17 | <string name="btn_demo_timeout">delayed jobs (timeout)</string> | |
| 18 | 18 | <string name="btn_demo_retrofit">Retrofit + RxJava</string> | |
| 19 | + <string name="btn_demo_double_binding_textview">Double binding (PublishSubject)</string> | ||
| 20 | + <string name="msg_demo_doublebinding">The "technique" used here is more useful than the wonderful calculation achieved below. Using this mechanism you can achieve something simliar to AngularJs or the ViewModel pattern pretty easily.</string> | ||
| 19 | 21 | </resources> | |
| Back | FazBrowse Home | New Git URL |
0 commit comments