2017-01-13 2 views
1

Ma vue comporte trois champs qui forment ensemble une équation. Ce que je veux réaliser est que dès que l'utilisateur remplit 2 champs sur 3, je calcule le restant.combineLatest pour les premiers éléments X de Y

Ce que je:

mObservableEditTextA = RxTextView.textChanges(mEditTextA); 
mObservableEditTextB = RxTextView.textChanges(mEditTextB); 
mObservableEditTextC = RxTextView.textChanges(mEditTextC); 

J'ai essayé de chaque paire de champs se la moissonneuse-batteuse dernière des deux autres sans succès.

Observable.combineLatest(mObservableEditTextA, mObservableEditTextB, (a, b) -> /* My action here */); 
Observable.combineLatest(mObservableEditTextA, mObservableEditTextC, (a, c) -> /* My action here */); 
Observable.combineLatest(mObservableEditTextB, mObservableEditTextC, (b, c) -> /* My action here */); 

Comment puis-je obtenir ce comportement?

Répondre

0

Il y a probablement un meilleur moyen d'y aller, mais vous pouvez attacher un horodateur d'émission à chaque événement, déterminer lequel d'entre eux était le dernier et émettre le reste. Identifiez ces événements par l'observable (champ) d'où ils viennent et décidez de l'élément qui manque dans la liste.

mObservableEditTextA = RxTextView.textChanges(mEditTextA) 
    .debounce(500, TimeUnit.MILLISECONDS) // So we don't flood the heap with lots of object construction, creating performance overhead due to garbage collection 
    .map(text -> Pair.create(new Date(), text)); 
mObservableEditTextB = RxTextView.textChanges(mEditTextB) 
    .debounce(500, TimeUnit.MILLISECONDS) 
    .map(text -> Pair.create(new Date(), text)); 
mObservableEditTextC = RxTextView.textChanges(mEditTextC) 
    .debounce(500, TimeUnit.MILLISECONDS) 
    .map(text -> Pair.create(new Date(), text)); 

Observable.combineLatest(mObservableEditTextA, mObservableEditTextB, mObservableEditTextC, (fieldAPair, fieldBPair, fieldCPair) -> { 
     firstField = ...; 
     secondField = ...; 
     // from timestamps determine which of the fields emitted last and return the other two with identifiers 
     return Arrays.asList(Pair.create(firstFieldIdentifier, firstField), Pair.create(secondFieldIdentifier, secondField)); 
    }) 
    .subscribe(result -> { 
     /* result is always a list of 2 items, more specifically 
      pairs of an identification in first position and new text 
      in the second. 

      Here you can look for the missing field in the list and 
      compute it from the other two */ 
    }) 

La logique permettant de déterminer celle que vous voulez calculer est dupliquée ici. Je l'ai fait juste pour ne pas avoir à emballer ces objets dans un nouvel objet et les paires imbriquées perdent leur lisibilité.

Vous pouvez toutefois traiter la position dans une liste comme un identificateur pour le champ, même si cela peut entraîner des erreurs. L'une ou l'autre de ces approches déplacerait la logique de détermination à la fois de l'opérateur abonné et de l'opérateur combineLatest uniquement vers l'abonné lui-même. Ton appel.