MvvM算是一個常見的程式架構之一,另外還有MVP、MVC等,練習寫架構可以有效的提高程式可讀性,等之後專案開發的越來越大時,activity隨之越來越大可能會不太好進行debug、後續處理,那麼今天來說說MvvM這個架構:
MvvM,整體來說我覺得跟MVP(Model-View-Presenter)有點類似,但不同的是ViewModel在處理數據的時候,也會將資訊更新至視圖(View)上,進階一點會與databinding(雙向綁定)、或LiveData做使用,而MvvM可拆分成三個部分:
接著就開始進行設計,首先先看到今日的UI:
我等等會透過factory先去建立一個初始化ViewModel及資料,然後透過按鈕在去設定資料,接著建立需要的data class(資料模型),主要有兩個欄位(account、password):
data class DataModel(
var account :String,
var password:String
)
接著設計需要的M層(Model),主要有data的getter&setter,加入DataModel至constructor,稍後會先從Factory來初始資料:
class MainRepository(model:DataModel){
private var data = model
//getter&setter
fun setData(account:String,password:String){
data.account=account
data.password=password
}
fun getData() = data
}
ViewModel(VM層),View通過此來更新Repository的資料。
class MainViewModel(model:DataModel) : ViewModel(){
private val repository= MainRepository(model)
fun setData(account: String , password:String){
repository.setData(account, password)
}
fun getData():DataModel{
return repository.getData()
}
}
實作ViewModelProvider.Factory內的create方法:
加入一個DataModel的constructor,之後會透過MainActivity從這邊建立MainModel。
class ViewModelFactory(val dataModel: DataModel): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MainViewModel(dataModel) as T
}
}
接著來設計主程式(View層):按鈕監聽&ViewModel建立
class MainActivity : AppCompatActivity(){
lateinit var mViewModel : MainViewModel
//建立資料
var data :DataModel = DataModel("Account2022","Password2022")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//viewmodel建立(viewOwner/通常是activity或fragment、Factory)
mViewModel = ViewModelProviders.of(this, ViewModelFactory(data)).get(MainViewModel::class.java)
txv_show.setText("Account:"+mViewModel.getData().account+"\n"+"Password:"+mViewModel.getData().password)
//按鈕監聽(將資料給ViewModel去更新data)
btn_send.setOnClickListener { view->
mViewModel.setData(et_account.text.toString(),et_password.text.toString())
txv_show.setText("Account:"+mViewModel.getData().account+"\n"+"Password:"+mViewModel.getData().password)
}
}
}
今天講的MvvM相對較簡易,因為還沒融合observe、LiveData及dataBinding做使用,那麼附上今天的成果圖: