RxJava와 데이터 바인딩으로 유효성 검사하기

많은 안드로이드 애플리케이션이 회원가입, 은행, 쇼핑몰 주문 등과 같은 곳에서 Email, 전화번호, 이름, 비밀번호 등을 사용자로 부터 입력 받는다.

사용자의 단순한 실수 또는 어뷰징을 막기 위해 각 폼의 유효성 검사를 해야한다.

회원가입을 예로들었을 때 유효성 검사를 하는 시점을 다음중 하나를 택할 수 있다.

  • 회원 가입 버튼을 눌렀을 때 모든 필드에 대한 유효성을 체크한다. 
  • 하나의 필드에 대해 독립적으로 유효성을 검사하는 버튼을 추가한다. 예) 중복 아이디 체크
  • 모든 필드에 대해 실시간으로 유효성 검사를 한다.

이 글에서는 3번째 방법을 사용한 예제를 다룰 것이다.

 

예를 들어, 위와 같이 사용자 이름을 입력받고 이름이 입력된 경우 체크모양의 이미지를 나타내는 애플리케이션있다고 상상해보자. 사용자에게 입력받은 이름을 실시간으로 처리하기 위해서 양방향 바인딩을 구현하고 이를 BehaviorSubject로 발행하여 유효성검사를 한 뒤 결과값을 구독하여 UI 를 갱신한다. 

 

위의 플로우 차트를 구현한 코드는 다음과 같다.

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <import type="android.view.View"/>
        <variable
            name="viewModel"
            type="com.charlezz.rxvalidation.MainViewModel" />
    </data>
        ...
        <EditText
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="Your name"
            android:text="@={viewModel.name}" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/baseline_done_black_18dp"
            android:visibility="@{viewModel.nameValid? View.VISIBLE: View.GONE}"
            />
        ...
</layout>
public class MainViewModel extends AndroidViewModel {
    public static final String TAG = MainViewModel.class.getSimpleName();

    private final BehaviorSubject<String> name = BehaviorSubject.createDefault("Charles");

    private final MutableLiveData<Boolean> nameValid = new InitMutableLiveData<>(false);
    
    private final CompositeDisposable disposables = new CompositeDisposable();

    public MainViewModel(Application application) {
        super(application);
        disposables.add(getNameValidator().subscribe(nameValid::postValue));
    }

    public String getName() {
        return name.getValue();
    }

    public void setName(String name) {
        this.name.onNext(name);
    }

    private Observable<Boolean> getNameValidator() {
        return name.map(str->{
            return !TextUtils.isEmpty(str);
        });
    }

    public MutableLiveData<Boolean> getNameValid() {
        return nameValid;
    }

    public MutableLiveData<Boolean> getEmailValid() {
        return emailValid;
    }

}
public class MainActivity extends AppCompatActivity {

    private MainViewModel viewModel;
    private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setLifecycleOwner(this);
        binding.setViewModel(viewModel);

    }
}

필드가 여러개인 경우 모든 필드를 유효성 검사를 통합적으로 하기 위해 combineLatest 연산자를 이용할 수 있다. 아래의 비디오를 확인하면 모든 필드가 유효할 때 SIGN UP 버튼이 활성화 되는것을 확인할 수 있다.

위 예제의 전체코드는 github에서 확인할 수 있다.

Buy me a coffeeBuy me a coffee
카테고리: AndroidRxJava

0개의 댓글

답글 남기기

이메일은 공개되지 않습니다.