iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 23
0
Mobile Development

大一之 Android Kotlin 自習心路歷程系列 第 23

[Day 23] Android in Kotlin: MVVM 架構分享 —— LiveData Observe 簡單示範

在 MVVM 架構裡面,livedata 是個在 lifecycle 依賴包裡面非常好用也十分常用的型態之一。

其中 livedata 又分為兩種

  • LiveData
  • MutableLiveData

MutableLiveData 是繼承於 LiveData 的抽象類別

package androidx.lifecycle;

@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

liveData 類最大的特徵就是它可以在 activity 透過 observer 得知資料的改變,從而做出動作。
這次的範例是在同一個 activity 中呈現,先在 edit text 中輸入文字,按下按鈕後更改 string,以後在底下的 text view 顯示該文字,非常簡單。

XML

一個 edit text 一個 button 一個 text view。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.MainActivity">

    <EditText
        android:id="@+id/editMain"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintVertical_bias="0.3"/>

    <Button
        android:id="@+id/btnMainSave"
        android:text="save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/editMain"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintVertical_bias="0.2"/>

    <TextView
        android:id="@+id/textMainResult"
        android:text="..."
        android:textSize="30sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/btnMainSave"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Respoitory

一樣把資料放在 repository 裡的 companion object,並用 livedata 包起來。
再用 init 方法初始化 data 為 "init",使其不為 null。

class MainRepository {
    companion object{
        private var data= MutableLiveData<String>()
    }

    init {
        data.value= "init"
    }
    
    fun saveText(text: String){
        data.value= text
    }

    fun getText() = data
}

在之前有提到,kotlin 的 getter and setter 會用成像是設定成員的值一樣

liveData 當然也是,value 就代表 liveData 裡的資料。

另外還有兩個 function 為 data 的 getter and setter。

ViewModel

一樣,複製一次 repository 裡的方法

class MainViewModel: ViewModel(){
    private val repository= MainRepository()

    fun saveText(text: String){
        repository.saveText(text)
    }

    fun getText() = repository.getText()
}

Activity

livedata 可以用 observe 方法偵測 liveData 是否有變化,如果有變化,就執行裡面的程式碼。也就是說,我這樣寫就代表當資料改變時,將其資料顯示在該 text view 上,

class MainActivity : AppCompatActivity() {

    private lateinit var edit: EditText
    private lateinit var btnSave: Button
    private lateinit var textResult: TextView

    private val viewModel: MainViewModel by lazy {
        ViewModelProvider(this, MyViewModelFactory()).get(MainViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        edit= findViewById(R.id.editMain)
        btnSave= findViewById(R.id.btnMainSave)
        textResult= findViewById(R.id.textMainResult)

        btnSave.setOnClickListener {
            viewModel.saveText(edit.text.toString())
            edit.text = null
        }

        viewModel.getText().observe(this, Observer{
            textResult.text= it
        })
    }
}

成果

在 edit text 打入 "安安"

當我按下 save 的瞬間,程式會 observe 到資料有變化,就會改變底下 text view 的內容了。


上一篇
[Day 22] Android in Kotlin: MVVM 架構分享 —— 簡單示範
下一篇
[Day 24] Android in Kotlin: 資料庫第一第二正規化入門
系列文
大一之 Android Kotlin 自習心路歷程30

尚未有邦友留言

立即登入留言