2015-10-21 60 views
2

我剛開始嘗試在此處學習RxJava/RxAndroid,並試圖驗證表單。我使用了Kaushik Gopal的lovely example here,並且很好地使我的編輯文本與combineLatest訂閱一起工作。現在我想觀察別的東西,作爲同一訂閱的一部分。我有一個按鈕來選擇一個出生日期,返回它的結果在我的Fragment的onActivityResult()函數。我需要什麼樣的觀察員?觀察RxJava中的基本自定義事件

private Observable<CharSequence> mNameChangeObservable; //etc. 
private Observable<Date> mDateChangeObservable; 

OnCreateView():

mIDNumberChangeObservable = RxTextView.textChanges(mIDNumberEditText).skip(1); 
mNameChangeObservable = RxTextView.textChanges(mNameEditText).skip(1); 
mEmailChangeObservable = RxTextView.textChanges(mEmailEditText).skip(1); 
mPasswordChangeObservable = RxTextView.textChanges(mPasswordEditText).skip(1); 

//mDateChangeObservable = ???; 

訂閱:

private void combineLatestEvents() { 
    mSubscription = Observable.combineLatest(mLLNumberChangeObservable, 
      mNameChangeObservable, 
      mEmailChangeObservable, 
      mPasswordChangeObservable, 
      mDateChangeObservable, 
      new Func5<CharSequence, CharSequence, CharSequence, CharSequence, Date, Boolean>() { 
       @Override 
       public Boolean call(CharSequence newIDNumber, 
            CharSequence newName, 
            CharSequence newEmail, 
            CharSequence newPassword, 
            Date newDate) { 

        boolean idNumberValid = !isEmpty(newIDNumber) && newIDNumber.length() == 8; 
        if (!idNumberValid) { 
         mLLNumberEditText.setError("Invalid ID Number!"); 
        } 

        boolean nameValid = !isEmpty(newName); 
        if (!nameValid) { 
         mNameEditText.setError("Invalid Name!"); 
        } 

        boolean emailValid = !isEmpty(newEmail) && 
          EMAIL_ADDRESS.matcher(newEmail).matches(); 
        if (!emailValid) { 
         mEmailEditText.setError("Invalid Email!"); 
        } 

        boolean passValid = !isEmpty(newPassword) && newPassword.length() >= 8; 
        if (!passValid) { 
         mPasswordEditText.setError("Invalid Password!"); 
        } 

        //Validate Date 

        return idNumberValid && nameValid && emailValid && passValid; 
       } 
      })// 
      .subscribe(new Observer<Boolean>() { 
       @Override 
       public void onCompleted() { 
       } 

       @Override 
       public void onError(Throwable e) { 
       } 

       @Override 
       public void onNext(Boolean formValid) { 
        if (formValid) { 
         mSubmitButton.setEnabled(true); 
        } else { 
         //Also print error here 
         mSubmitButton.setEnabled(false); 
        } 
       } 
      }); 
} 

OnActivityResult:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode != Activity.RESULT_OK) return; 
    if (requestCode == REQUEST_DATE) { 
     mDate = (Date) data.getSerializableExtra(Constants.Extras.EXTRA_DATE); 
     updateDobButtonText(mDate); 

     //Somehow tell my subscription I have a new date 
    } 
} 

回答

1

你可以按照你目前的模式獲取某個按鈕事件。 ButtonTextView的子類,因此您可以撥打RxTextView.textChanges()並以Button作爲參數。它會在按鈕文本更改時發出項目。具體而言,如果這條線

updateDobButtonText(mDate); 

調用Button.setText(),你應該得到你的訂戶的事件。

+0

感謝我有那種想通這一點,看到了RxView類的更多相關作品。我想我正在尋找一種方法來觀察任何正在更新的任意變量,我認爲這很容易!下面的解決方案是我已經走了,雖然我還不確定它是最好的。 –

0

好了很多更多的谷歌搜索後,我得出結論,正常的方式來鉤入生命週期事件將使用Trello's RxLifeCycle library。然而,因爲我只想發起一個簡單的同步事件,並且我知道何時(在onActivityResult期間),這是我找到的解決方案:

(1)創建主題 - 在這種情況下,我認爲PublishSubject是最好的,因爲它只是一個需要發射的物體。

private PublishSubject<Date> mDateSubject = PublishSubject.create(); 

(2)將它轉換爲一個可以監聽主線程事件的Observable。

public Observable<Date> makeDateObservable() { 
    return mDateSubject.observeOn(AndroidSchedulers.mainThread()); 
} 

(3)通過對主體調用next()發射物體的時候,我們就會明白:

mDateSubject.onNext(mDate); 
相關問題