Hướng dẫn sử dụng RxJava và RxBinding trong phát triển giao diện người dùng

Thema

  • Trình diện ứng dụng bao gồm ba trường Nhập liệu và một Nhãn Text.
  • Yêu cầu: Nhãn Text hiển thị tổng của ba trường Nhập liệu một cách thời gian thực.
  • Nếu dữ liệu nhập không phải là số, coi giá trị đó là 0.
  • Giá trị ban đầu của ba trường Nhập liệu lần lượt là 1, 2, 3.

Tạo mới dự án

Mở Android Studio và tạo mới dự án qua File / New / Project...

Trong trang hướng dẫn tạo dự án đầu tiên, điền tên ứng dụng là RxExample và tích chọn Include Kotlin support.

Trên trang hướng dẫn thứ tư, nhấn nút Finish để tạo dự án.

Cập nhật build.gradle

            
                apply plugin: 'com.android.application'
                apply plugin: 'kotlin-android'
                apply plugin: 'kotlin-android-extensions'

                android {
                    compileSdkVersion 28
                    buildToolsVersion '28.0.2'
                    defaultConfig {
                        applicationId "com.zwstudio.rxexample"
                        minSdkVersion 15
                        targetSdkVersion 28
                        versionCode 1
                        versionName "1.0"
                        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
                    }
                    buildTypes {
                        release {
                            minifyEnabled false
                            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                        }
                    }
                }

                dependencies {
                    implementation fileTree(dir: 'libs', include: ['*.jar'])
                    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
                    implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
                    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
                    testImplementation 'junit:junit:4.12'
                    androidTestImplementation 'com.android.support.test:runner:1.0.2'
                    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
                    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
                    implementation 'io.reactivex.rxjava2:rxjava:2.1.16'
                    implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'
                    implementation 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.1.1'
                }
            
        

Cấu hình giao diện người dùng

Mở file activity_main.xml và thay thế phần TextView mặc định bằng cấu trúc GridLayout sau:

            
                <GridLayout
                    android:layout_width="120dp"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    android:rowCount="5"
                    android:columnCount="2">

                    <EditText
                        android:id="@+id/edtSo1"
                        android:layout_width="80dp"
                        android:layout_height="wrap_content"
                        android:gravity="end"
                        android:layout_row="0"
                        android:layout_column="1"
                        android:inputType="number"
                        android:hint="0"
                        android:text="1" />

                    <EditText
                        android:id="@+id/edtSo2"
                        android:layout_width="80dp"
                        android:layout_height="wrap_content"
                        android:gravity="end"
                        android:layout_row="1"
                        android:layout_column="1"
                        android:inputType="number"
                        android:hint="0"
                        android:text="2" />

                    <TextView
                        android:id="@+id/tvCong"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_row="2"
                        android:layout_column="0"
                        android:gravity="end"
                        android:text="+"
                        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

                    <EditText
                        android:id="@+id/edtSo3"
                        android:layout_width="80dp"
                        android:layout_height="wrap_content"
                        android:layout_row="2"
                        android:layout_column="1"
                        android:gravity="end"
                        android:inputType="number"
                        android:hint="0"
                        android:text="3" />

                    <TextView
                        android:id="@+id/tvKetQua"
                        android:layout_row="3"
                        android:layout_column="1"
                        android:layout_width="76dp"
                        android:gravity="end"
                        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
                        android:text="16"  />
                </GridLayout>
            
        

Biến kiểm soát

            
                val edtSo1 = findViewById<EditText>(R.id.edtSo1)
                val edtSo2 = findViewById<EditText>(R.id.edtSo2)
                val edtSo3 = findViewById<EditText>(R.id.edtSo3)
                val tvKetQua = findViewById<TextView>(R.id.tvKetQua)
            
        

Giải pháp truyền thống không sử dụng RxJava

            
                val theoDoiText = object : TextWatcher {
                    override fun afterTextChanged(s: Editable?) {
                    }

                    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                    }

                    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                        val so1 = edtSo1.text.toString().toIntOrNull() ?: 0
                        val so2 = edtSo2.text.toString().toIntOrNull() ?: 0
                        val so3 = edtSo3.text.toString().toIntOrNull() ?: 0
                        tvKetQua.text = (so1 + so2 + so3).toString()
                    }

                }
                edtSo1.addTextChangedListener(theoDoiText)
                edtSo2.addTextChangedListener(theoDoiText)
                edtSo3.addTextChangedListener(theoDoiText)
                edtSo1.text = edtSo1.text
            
        

Giải pháp sử dụng RxJava

            
                Observable.combineLatest(
                    RxTextView.textChanges(edtSo1),
                    RxTextView.textChanges(edtSo2),
                    RxTextView.textChanges(edtSo3)
                ) { nhan1, nhan2, nhan3 ->
                    val so1 = nhan1.toString().toIntOrNull() ?: 0
                    val so2 = nhan2.toString().toIntOrNull() ?: 0
                    val so3 = nhan3.toString().toIntOrNull() ?: 0
                    (so1 + so2 + so3).toString()
                }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(RxTextView.text(tvKetQua))
            
        

Thẻ: RxJava RxBinding Kotlin Android Phát triển GUI

Đăng vào ngày 21 tháng 6 lúc 00:18