This article is aimed at the Rx family’s understanding of the students… otherwise it will be a little trouble to learn oh! (jakewharton)

RxBinding: RxBinding: RxBinding: RxBinding: RxBinding: RxBinding: RxBinding: RxBinding








Ok, now that we’ve understood the three steps above, let’s begin to understand the magic of RxBinding. In fact, there are many bloggers who have written about the use of RxBinding, and they are very detailed. If you want to learn about it, you can search for it. Without further ado, let’s talk about how the RxBinding can be written by hand.

1. Let’s start with RxView. See how god is written, as for its advantages I will not say this, want to know can Google. Here’s how to use RxView

RxView.clicks(forgetPwd) .throttleFirst(1,TimeUnit.SECONDS) .subscribe(new Action1<Void>() { @Override public void call(Void aVoid) { startActivityForResult(new Intent(context,ResetPwdActivity.class),1); }});Copy the code

See that Clicks is a static method that returns an Observable and subscribes to an Observer, but we can also do things like button stabilization, postponement, filtering before Observer. Let’s analyze the source code of RxView and see how it is written, please see the following (just to mention some important source content).

@CheckResult @NonNull
public static Observable<Void> clicks(@NonNull View view) {    
checkNotNull(view, "view == null");  
return Observable.create(new ViewClickOnSubscribe(view));
}Copy the code

Clicks pass in a view and create an Observable via observable. create. Since the setOnClickListener event returns the current object, we simply miswrite the generic Void. Ok, now the most important thing to come, is the content of the ViewClickOnSubscribe class, how to wear the click to subscribe content.

final class ViewClickOnSubscribe implements Observable.OnSubscribe<Void> { final View view; ViewClickOnSubscribe(View view) { this.view = view; } @Override public void call(final Subscriber<? super Void> subscriber) { checkUiThread(); View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { if (! subscriber.isUnsubscribed()) { subscriber.onNext(null); }}}; view.setOnClickListener(listener); subscriber.add(new MainThreadSubscription() { @Override protected void onUnsubscribe() { view.setOnClickListener(null); }}); }}Copy the code

ViewClickOnSubscribe, which implements observable. OnSubscribe<T>. The constructor passes the View in. Click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view) {click (view); Now that we implement ViewClickOnSubscribe, we can listen for the view click event in the call callback method and pass it to the observer. As you can see in the code, we’ve implemented the OnClickListener method. Then in onClick we subscribers call back to this event. The subscriber also adds an unsubscribe operation, and when the subscription is unsubscribed, listening on the view stops.

Click on RxView to see not only clicks, but also many other functions, such as pressed, selected, and Visibility, which are all encapsulated again. If you are interested, you can explore them.

The next point is to write your own RxBinding. Let me take the sensor as an example and describe the steps to do this.

public class TestActivity extends Activity implements SensorEventListener {           
       SensorManager sensormanager;    
       @Override    
       public void onCreate(Bundle savedInstanceState) {        
              super.onCreate(savedInstanceState);                    
              setContentView(R.layout.activity_main);        
              sensormanager =       
              (SensorManager)getSystemService(Context.SENSOR_SERVICE);            
                    sensormanager.registerListener(this,                    
                sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),                    
                SensorManager.SENSOR_DELAY_GAME);   
 }    
    @Override   
    public void onSensorChanged(SensorEvent event) {
            }    
    @Override   
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
            }    

    @Override    
    protected void onDestroy() {        
        super.onDestroy();        
        sensormanager.unregisterListener(this);    
}}Copy the code

Sensor information callback right, through onSensorChanged to get the gravity acceleration of the three axes, the onAccuracyChanged method is almost not used, we do not need to write, but because of SensorEventListener we must implement. And the sensor’s three axes of gravity pull back at a speed you can’t control. This can only be done through code logic. But packaging it as an RxBinding not only reduces the amount of code, but also allows you to control the speed of gravity callback for the three axes. But how can we package it into an RxBinding? At this point we can imitate it according to the RxView we analyzed above. It will not write well, but we can imitate it. Okay, so now let’s analyze how we can miswrite RxView. First of all, we created the RxSensor (RxView) class. Analysis, we need to observe what, of course is the sensor (nonsense), so we how we observe it! Good question, that is to implement a SensorEventListener in order to look at the sensor, so we need to look at something to receive this listener, and then we need the SensorManager (View) to pass in this class. Let’s next create the observer of the sensor

public static Observable<float[]> registerSensor(SensorManager sensorManager){    
return Observable.create(new SensorChangeOnSubscribe(sensorManager));
}Copy the code

May I have a feeling of deja vu? May I have a feeling of deja vu? However, we need to get the sensor data in this, need to write the wrong generic array form, in fact, the focus of course is SensorChangeOnSubscribe this class of specific content, I believe many friends have been impatient.

public class SensorChangeOnSubscribe implements Observable.OnSubscribe<float[]> { final SensorManager sensormanager; public SensorChangeOnSubscribe(SensorManager sensormanager) { this.sensormanager = sensormanager; } @Override public void call(final Subscriber<? super float[]> subscriber) { final SensorEventListener listener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { float[] values = event.values; subscriber.onNext(values); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; sensormanager.registerListener(listener, sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); subscriber.add(new MainThreadSubscription() { @Override protected void onUnsubscribe() { sensormanager.unregisterListener(listener); }}); The subscriber. OnNext (new float [] {0, 0}). }}Copy the code

We register the sensor through the SensorChangeOnSubscribe constructor to the SensorManager, and then we get the SensorEvent data through the sensor callback and the subscriber sends the data back out, and the observer gets the data. OnNext (new float[]{0,0,0}); onAccuracyChanged (); , do not know can look at the source of RxTextView. I’m sure you’ll see. Next, I’ll show you the Activity implemented with RxSensor

public class TestActivity extends Activity { SensorManager sensormanager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sensormanager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); RxSensor.registerSensor(sensormanager) .debounce(1, Timeunit.seconds). Subscribe (new Action1<float[]>() {@override public void Call (float[] floats) {// Take out sensor data}}); }}Copy the code

Isn’t it much, much, much easier? That’s the magic of the RxBinding. Debounce is delayed, which is the equivalent of fetching data once per second. All right, that’s it. I’m so tired. I’m gonna go rest.