2016-05-12 16 views
1

Ich versuche, in reaktive Programmierung zum ersten Mal zu kommen, also bitte gehen Sie einfach auf mich. Ich verwende die ReactiveLocation Bibliothek für Android, und ich habe 4 Textansichten, die mit Standortdaten gefüllt werden müssen, wenn ein neuer Standort empfangen wird.RxAndroid: Wie man einen Strom richtig in 4 Aktionen spaltet:

Also das ist der Code, der mir eine Stelle an jedem Standort Update erhalten:

locationProvider = new ReactiveLocationProvider(getApplicationContext()); 
    lastKnownLocationObservable = locationProvider.getLastKnownLocation(); 

    final LocationRequest locationRequest = LocationRequest.create() 
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
      .setNumUpdates(150) 
      .setInterval(100); 
    locationUpdatesObservable = locationProvider 
      .checkLocationSettings(
        new LocationSettingsRequest.Builder() 
          .addLocationRequest(locationRequest) 
          .setAlwaysShow(true) //Refrence: http://stackoverflow.com/questions/29824408/google-play-services-locationservices-api-new-option-never 
          .build() 
      ) 
      .doOnNext(new Action1<LocationSettingsResult>() { 
       @Override 
       public void call(LocationSettingsResult locationSettingsResult) { 
        Status status = locationSettingsResult.getStatus(); 
        if (status.getStatusCode() == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) { 
         try { 
          status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS); 
         } catch (IntentSender.SendIntentException th) { 
          Log.e("MainActivity", "Error opening settings activity.", th); 
         } 
        } 
       } 
      }) 
      .flatMap(new Func1<LocationSettingsResult, Observable<Location>>() { 
       @Override 
       public Observable<Location> call(LocationSettingsResult locationSettingsResult) { 
        return locationProvider.getUpdatedLocation(locationRequest); 
       } 
      }); 

ich auch dieses Func haben, die den Ort in ein Array von 4 Strings aufgeteilt wird:

public class LocationToStringsArrayListFunc implements Func1<Location, ArrayList<String>> { 
    @Override 
    public ArrayList<String> call(Location location) { 
     ArrayList<String> locationDetails = null; 
     if (location != null) { 
      locationDetails = new ArrayList<>(); 
      locationDetails.add(String.valueOf(location.getLatitude())); 
      locationDetails.add(String.valueOf(location.getLongitude())); 
      locationDetails.add(String.valueOf(location.getTime())); 
      locationDetails.add(String.valueOf(location.getSpeed())); 
     } 
     return locationDetails; 
    } 
} 

Finaly ich habe diese Aktion die Textview mit Text pupulate:

public class DisplayTextOnViewAction implements Action1<String> { 
    private final TextView target; 

    public DisplayTextOnViewAction(TextView target) { 
     this.target = target; 
    } 

    @Override 
    public void call(String s) { 
     target.setText(s); 
    } 
} 

Was ich jetzt will, ist aufgeteilt dieser Strom jedes Mal bis 4 Ansichten, ich weiß, dass für einen tun, ich folgendes:

mUpdatableLocationSubscription = locationUpdatesObservable 
      .map(new LocationToStringsArrayListFunc()) 
      .map(new Func1<ArrayList<String>, String>() { 

       @Override 
       public String call(ArrayList<String> stringArrayList) { 
        return stringArrayList.get(0); 
       } 
      }) 
      .subscribe(new DisplayTextOnViewAction(tvLatitudeValue), new ErrorHandler()); 

Meine Frage ist: LongitudeValue, tvLastUpdateValue, tvSpeedValue mit dem gleichen Strom: Wie die anderen drei Textview ist popluate ?

Vielen Dank im Voraus.

Antwort

4

.share() Operator ist, was Sie suchen sollten.

Mit dieser "Helfer" -Klasse:

public class ListItemFunc extends Func1<ArrayList<String>, String>{ 

    private final int index; 

    public ListItemFunc(int index) { 
     this.index = index; 
    } 

    @Override 
    public String call(ArrayList<String> strings) { 
     return strings.get(index); 
    } 
} 

Ihr Code kann wie folgt aussehen:

Observable<ArrayList<String>> sharedObservable = 
     locationUpdatesObservable.map(new LocationToStringsArrayListFunc()).share(); 

latitudeSubscription = sharedObservable 
     .map(new ListItemFunc(0)) 
     .subscribe(new DisplayTextOnViewAction(tvLatitudeValue), new ErrorHandler()); 

longitudeSubscription = sharedObservable 
     .map(new ListItemFunc(1)) 
     .subscribe(new DisplayTextOnViewAction(tvLongitudeValue), new ErrorHandler()); 

lastUpdateSubscription = sharedObservable 
     .map(new ListItemFunc(2)) 
     .subscribe(new DisplayTextOnViewAction(tvLastUpdateValue), new ErrorHandler()); 

speedSubscription = sharedObservable 
     .map(new ListItemFunc(3)) 
     .subscribe(new DisplayTextOnViewAction(tvSpeedValue), new ErrorHandler()); 
+0

Danke für Ihre Hilfe, getestet und funktionierte gut. –

Verwandte Themen