テキストの入力状態でボタンを有効・無効化する
テキストボックスに入力したときだけ押せるボタンを作りたい。
(空のときはdisable、文字があるときはenableにしたい。)
実装手順
テキストボックスは双方向バインディングでLiveData
と連携されている前提とする。
LiveData
を使用した双方向バインディングについては【Android,Kotlin】双方向・単方向データバインディングの実装手順を参照
MediatorLiveDataで別のLiveDataの変更を監視する
MediatorLiveData
は別のLiveData
の変更にフックして処理を実行できるLiveData
。
ボタンの状態を保持するLiveData
をMediatorLiveData
で定義し、別のLiveData
の変更に連動して値を変更する。
以下のコードではテキストボックスに双方向バインディングされているLiveData
の変更を監視して
ボタンの状態を保持するためにMediatorLiveData
型でbuttonEnabled
変数を定義しておく。
class FirstViewModel : ViewModel() {
// テキストボックスに双方向バインディングされている LiveData
val username = MutableLiveData("")
// 他のLiveDataを監視するためにMediatorLiveDataでボタンの状態を保持する
val buttonEnabled = MediatorLiveData<Boolean>()
init {
// addSourceで連携. usernameが変更されたときに validate() を呼び出す.
buttonEnabled.addSource(username) { validate() }
}
// usernameが変更されたとき、空ならボタンをdisableにする
private fun validate() {
buttonEnabled.value = username.value?.isNotEmpty() ?: false
}
}
初期化時にaddSource
メソッドでusername
を引数に渡すとusername
の変更時にvalidate()
が呼び出されるようになる。
もしさらに連携したいLiveData
がある場合は、さらにaddSource
メソッドを呼び出せばよい。
レイアウト: 作成したMediatorLiveDataの値のデータバンディングでボタンをenable/disableする
ボタンに対して単方向バインディング(@{}
)する。
(レイアウト関連の属性などは省略)
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
tools:context=".FirstFragment">
<data>
<variable
name="viewModel"
type="com.example.myapplication.FirstViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout>
<EditText
android:id="@+id/username"
android:text="@={viewModel.username}" />
<Button
android:id="@+id/button"
android:text="@string/next"
android:enabled="@{viewModel.buttonEnabled}" /> <!-- 単方向バインディング -->
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
\確かな知識を身に着けたい、Androidアプリ開発を学びたい人にオススメ!/