前言
实现MVVM并不一定要使用Databinding,但是使用它可以方便你绑定数据,建议使用。可以通过查看以下两篇文章简单的了解DataBinding、ViewModel的使用。
在使用了MVVM之后让人耳目一新,特别是结合LiveData和DataBinding之后,对数据的操作降低了,同时也就增加了阅读性和可维护性,这也是建议使用的主要原因。
1 预览实现效果
2 View
使用Databinding进行数据绑定,网络请求到的数据可以直接驱动UI。
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="MainViewModel"
type="com.example.mvvmdemo.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/btn"
android:layout_width="128dp"
android:layout_height="48dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="@{MainViewModel.strLiveData}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3 Activity
3.1 BaseActivity
通过泛型以及实例进行初始化,方便View与ViewModel进行互操作。
abstract class BaseActivity<binding : ViewDataBinding, viewModel : BaseViewModel> :
AppCompatActivity() {
lateinit var binding: binding
lateinit var viewModel: viewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, setLayoutId())
viewModel = getVMInstance()
binding.setVariable(getViewModelBR(), viewModel)
operateUI()
AppDatabase.getInstance(this)!!.userDao().queryUser().observe(this, Observer {
//operate
})
}
abstract fun getVMInstance(): viewModel
abstract fun getViewModelBR(): Int
abstract fun setLayoutId(): Int
private fun operateUI() {
viewModel.dismissDialog.observe(this, Observer {
//dismiss
})
viewModel.finishActivity.observe(this, Observer {
finish()
})
}
}
3.2 MainActivity
继承BaseActivity然后进行初始化以及后续的操作
class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.request()
}
override fun setLayoutId(): Int {
return R.layout.activity_main;
}
override fun getVMInstance(): MainViewModel {
return MainViewModel(application)
}
override fun getViewModelBR(): Int {
return BR.MainViewModel
}
}
4 ViewModel
4.1 BaseViewModel
封装ViewModel,赋予BaseViewModel一些基础能力,比如关闭dialog、退出Activity等。
abstract class BaseViewModel(application: Application) : AndroidViewModel(application) {
var dismissDialog: MutableLiveData<Unit> = MutableLiveData()
var finishActivity: MutableLiveData<Unit> = MutableLiveData()
fun dismissDialog() {
dismissDialog.value = null
}
}
4.2 MainViewModel
继承BaseViewModel进行一些业务层的操作。
class MainViewModel(application: Application) : BaseViewModel(application) {
var strLiveData = ObservableField<String>()
/*
* 模仿网络请求
* */
fun request() {
Observable.just(1)
.delay(5,TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
strLiveData.set("没错,就是我~")
//AppDatabase.getInstance(getApplication())!!.userDao().insertUser(User())
dismissDialog()
}
}
}
5 Model
因为项目中使用数据库较多,项目中使用的是Room
,因此对Room进行封装,通过单例直接操作数据库。Room的具体使用请自行查看官网。
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
private var sDatabase: AppDatabase? = null
private val sObject = Any()
fun getInstance(context: Context): AppDatabase? {
if (sDatabase == null) {
synchronized(sObject) {
if (sDatabase == null) { //允许主线程访问数据库,默认是不允许
sDatabase = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"database-name"
)
.fallbackToDestructiveMigration()
// .addMigrations(migrations3_4)
// .allowMainThreadQueries()
.build()
}
}
}
return sDatabase
}
}
}
@Dao
public interface UserDao {
@Insert
long insertUser(User users);
@Query("SELECT * FROM user")
LiveData<List<User>> queryUser();
}
@Entity
public class User {
@PrimaryKey(autoGenerate = true)
public int uid;
}
总结
实现MVVM只要分为以下3个步骤:
- 1 实现ViewModel
- 2 在xml中进行数据绑定
- 3 关联xml和VewModel
对于数据的持久化,可根据自己的项目进行封装,也可以在初始化的时候手动注入到ViewModel中。