前言
?實(shí)現(xiàn)MVVM并不一定要使用Databinding年枕,但是使用它可以方便你綁定數(shù)據(jù),建議使用∪嗟郑可以通過查看以下兩篇文章簡單的了解DataBinding亡容、ViewModel的使用。
?在使用了MVVM之后讓人耳目一新冤今,特別是結(jié)合LiveData和DataBinding之后闺兢,對數(shù)據(jù)的操作降低了,同時(shí)也就增加了閱讀性和可維護(hù)性戏罢,這也是建議使用的主要原因屋谭。
相關(guān)文章閱讀
MVVM(一) DataBinding的使用
MVVM(二) ViewModel的使用
1 預(yù)覽實(shí)現(xiàn)效果
2 View
?使用Databinding進(jìn)行數(shù)據(jù)綁定,網(wǎng)絡(luò)請求到的數(shù)據(jù)可以直接驅(qū)動(dòng)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
?通過泛型以及實(shí)例進(jìn)行初始化桐磁,方便View與ViewModel進(jìn)行互操作。
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然后進(jìn)行初始化以及后續(xù)的操作
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一些基礎(chǔ)能力所意,比如關(guān)閉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進(jìn)行一些業(yè)務(wù)層的操作。
class MainViewModel(application: Application) : BaseViewModel(application) {
var strLiveData = ObservableField<String>()
/*
* 模仿網(wǎng)絡(luò)請求
* */
fun request() {
Observable.just(1)
.delay(5,TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
strLiveData.set("沒錯(cuò)泄鹏,就是我~")
//AppDatabase.getInstance(getApplication())!!.userDao().insertUser(User())
dismissDialog()
}
}
}
5 Model
?因?yàn)轫?xiàng)目中使用數(shù)據(jù)庫較多郎任,項(xiàng)目中使用的是Room
,因此對Room進(jìn)行封裝备籽,通過單例直接操作數(shù)據(jù)庫舶治。Room的具體使用請自行查看官網(wǎng)。
@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) { //允許主線程訪問數(shù)據(jù)庫车猬,默認(rèn)是不允許
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;
}
總結(jié)
?實(shí)現(xiàn)MVVM只要分為以下3個(gè)步驟:
- 1 實(shí)現(xiàn)ViewModel
- 2 在xml中進(jìn)行數(shù)據(jù)綁定
- 3 關(guān)聯(lián)xml和VewModel
?對于數(shù)據(jù)的持久化霉猛,可根據(jù)自己的項(xiàng)目進(jìn)行封裝,也可以在初始化的時(shí)候手動(dòng)注入到ViewModel中珠闰。