代码之家  ›  专栏  ›  技术社区  ›  davisjp

使用RxJava2对ViewModel进行EditText验证

  •  0
  • davisjp  · 技术社区  · 7 年前

    我试图在单击按钮时使用RxJava对EditText执行验证,但我很难将验证移到ViewModel,这将使测试更容易。我正在使用Jake Wharton提供的RxBindings来获取UI输入和RxJava2的可流动性。当我单击AlertDialog上的按钮时,将ElateTest与PublishSubject组合以触发Flowable。以下是我目前得到的信息:

    private Flowable<CharSequence> projectTitleObservable;
    private final PublishSubject<CharSequence> createProjectClicked = PublishSubject.create();
    
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Context context = getActivity();
    
        View dialogView = LayoutInflater.from(context).inflate(R.layout.new_project, null);
    
        ButterKnife.bind(this, dialogView);
    
        projectTitleObservable = RxTextView.textChanges(projectNameEditText).toFlowable(BackpressureStrategy.LATEST);
    
        ConnectableFlowable <CharSequence> connectableFlowable = Flowable.combineLatest(createProjectClicked.toFlowable(BackpressureStrategy.LATEST), projectTitleObservable, (ignored, title) -> {
            boolean validTitle = !TextUtils.isEmpty(title);
            if (!validTitle) {
                projectNameEditText.setError("Project must have a name");
            }
    
            Timber.d("Hey, lambdas work! Look -> " + title);
            return title;
        })
                .publish();
    
        connectableFlowable.subscribe(test -> Timber.d(test.toString()));
    
        return new AlertDialog.Builder(context)
                .setTitle("Add new Project")
                .setView(dialogView)
                .setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
                    Timber.d("Ok clicked!");
                    createProjectClicked.onNext("It works!");
                })
                .setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> Timber.d("Cancel clicked!"))
                .create();
    }
    

    我只是在同一个地方发布和订阅,以确保它在将ConnectableFlowable移动到ViewModel之前实际工作。我得到的唯一日志是“点击Ok!”对我来说,这意味着它从未被订阅过。知道为什么没有订阅吗?

    2 回复  |  直到 7 年前
        1
  •  0
  •   Leandro Borges Ferreira    6 年前

    我可以使用平面图实现这种行为。下面是一个示例,说明如何在文本有效的情况下显示祝酒词:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    
        val btnSubject = PublishSubject.create<Boolean>()
        val textObservable = RxTextView.textChangeEvents(editText)
                .filter { validateText(it.text().toString()) }
    
        btnSubject.flatMap { textObservable }
                .subscribe({
                    Toast.makeText(this, "Text is correct", Toast.LENGTH_SHORT).show()
                })
    
    
        btn.setOnClickListener {
            btnSubject.onNext(true)
        }
    }
    
    private fun validateText(text: String) = text.length >= 5
    

    如果需要在文本不正确时显示一些反馈,可以更改地图的过滤器并按如下方式使用:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    
        val btnSubject = PublishSubject.create<Boolean>()
        val textObservable = RxTextView.textChangeEvents(editText)
                .map { validateText(it.text().toString()) }
    
        btnSubject.flatMap { textObservable }
                .subscribe({ isTextCorrect ->
                    if (isTextCorrect) {
                        Toast.makeText(this, "Text is correct", Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this, "Text NOT is correct", Toast.LENGTH_SHORT).show()
                    }
                })
    
    
        btn.setOnClickListener {
            btnSubject.onNext(true)
        }
    }
    
    private fun validateText(text: String) = text.length >= 5
    

    我刚刚测试了这段代码,效果很好。

    快乐的代码!

        2
  •  0
  •   davisjp    6 年前

    Java版本:

    private Observable<TextViewTextChangeEvent> taskTitleObservable;
    private final PublishSubject<Boolean> createTaskClicked = PublishSubject.create();
    
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);
    
        taskTitleObservable = RxTextView.textChangeEvents(taskTitle)
        .filter(event -> validateText(event.text().toString()));
    
        createTaskClicked.flatMap(test -> taskTitleObservable).subscribe( aVoid -> {
            Toast.makeText(getActivity(), "Text is correct", Toast.LENGTH_SHORT).show();
        });
    
        RxView.clicks(fab).subscribe(aVoid -> {
            createTaskClicked.onNext(true);
        });
    }
    
    private Boolean validateText (String text) {
        return text.length() >= 5;
    }
    

    如果文本不正确,则反馈:

    private Observable<Boolean> taskTitleObservable;
    private final PublishSubject<Boolean> createTaskClicked = PublishSubject.create();
    
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);
    
        taskTitleObservable = RxTextView.textChangeEvents(taskTitle)
                .map(event -> validateText(event.text().toString()));
    
        createTaskClicked.flatMap(test -> taskTitleObservable).subscribe( isTextCorrect -> {
            if (isTextCorrect) {
                Toast.makeText(getActivity(), "Text is correct", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getActivity(), "Text is incorrect", Toast.LENGTH_SHORT).show();
            }
        });
    
        RxView.clicks(fab).subscribe(aVoid -> {
            createTaskClicked.onNext(true);
        });
    }
    
    private Boolean validateText (String text) {
        return text.length() >= 5;
    }