2017-01-22 3 views
2

J'utilise la liaison de données android et je veux créer un observable à partir des données de texte d'édition afin que je puisse effectuer des opérations à l'aide de rxjava. Ceci est mon code.Créer un observable à partir d'un texte d'édition

Le XML

<EditText 
      android:id="@+id/edit_text_username" 
      android:layout_width="match_parent" 
      android:addTextChangedListener="@{viewModel.getUsername}" 
      android:background="@drawable/border_edit_top" 
      android:drawableLeft="@drawable/ic_person_white_24px" 
      android:drawablePadding="10dp" 
      android:drawableStart="@drawable/ic_person_white_24px" 
      android:hint="@string/username" 
      android:inputType="text" 
      android:paddingEnd="10dp" 
      android:paddingLeft="10dp" 
      android:paddingRight="10dp" 
      android:paddingStart="10dp" 
      app:layout_heightPercent="10%" /> 

La classe ViewModel

public TextWatcher getUsername() { 
    return new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      Log.i("username", s.toString()); 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 

     } 
    }; 
} 

J'ai 3 ces textes d'édition sur laquelle je veux utiliser l'opérateur combinelatest de rx java pour la forme validations.How exactement ce que je vais à propos de l'implémentation de rx java dans ce scénario?

+0

Vous pouvez suivre le guide sur https://medium.com/tangoagency/rxjava-meets-android-data-binding-4ca5e1144107 – tynn

+0

Pouvez-vous essayer de instancier the'TextWatcher' pour lui-même et non par un getter ? Quelque chose comme 'public TextWatchern textWatcher = nouveau TextWatcher (...)' et 'android: addTextChangedListener =" @ {viewModel.textWatcher} "'. Je pense que vous pouvez également créer un getter public pour le 'TextWatcher' et rendre le champ lui-même' private'. – yennsarah

Répondre

3

Vous pouvez utiliser RxBinding. Cet exemple pourrait vous aider.

//Validate username field 
Observable<Boolean> usernameObservable = RxTextView.textChanges(usernameEditText) 
       .map(username -> StringUtils.isNotBlank(username) && Validators.validateUsername(username.toString())).skip(1); 

//Validate password field 
Observable<CharSequence> passwordObservable = RxTextView.textChanges(passwordEditText).skip(1); 

//Validate confirm password field 
Observable<CharSequence> confirmPasswordObservable = RxTextView.textChanges(confirmPasswordEditText) 
       .skip(1); 

//Validate password matches field 
Observable<Boolean> passwordMatcherObservable = Observable.combineLatest(passwordObservable, confirmPasswordObservable, 
       (password, confirmPassword) -> password.toString().equals(confirmPassword.toString())).skip(1); 

Observable.combineLatest(passwordMatcherObservable, usernameObservable, 
       (passwordMatch, isUsernameValid) -> passwordMatch && isUsernameValid) 
       .distinctUntilChanged() 
       .subscribe(valid -> createAccountBtn.setEnabled(valid)); 
+0

pourquoi vous mettez '.skip (1)'? – MBH

+2

La première fois que les champs sont vides, j'ai donc un InputTextLayout et je veux éviter la première validation. – AndroidRuntimeException

+0

J'ai vérifié plus tard, ils disent aussi que parce que l'événement BeforeTextChange est appelé pour le texte existant en cours de l'EditText. – MBH