本博客仅为小白个人学习记录,不作为任何教学指导,读者所见内容仅供参考,如有错误,欢迎指正,非常感谢。
MVVM+DataBing+LiveData+RxJava架构
先看Demo的架构图示:
- 首先在model中,也就是数据来源,通过RxJava+Retrofit的方式(单例类Rretrofit对象,Json解析,网络接口等),获得从APi的网络数据。
- 获得数据后,需要调用viewmodel类中相应的属性,这个属性类型是MutableLiveData,将数据赋值给livedata。
- 由于在Activity中,设置了viewmodel属性改变时,通知Activity。同时,将viewmodel对象,赋值给databing.
viewModel.counter.observe(this, Observer {
binding.viewmodel = viewModel
})
- Databing的视图数据对象发生改变后,就会更新与数据视图对象相关联的XML文件中控件的值。这样网络数据就转化成了视图显示在UI界面中。
网络数据API地址:
Api地址
1.实体类,用于接收网络数据,并通过Gson解析,生成对应的对象:
data class Translation(val status:String,
val message:String,
val user:User) {
class User(val inter: Int,
val name:String,
val mobile:String,
val created_at:String,
val updated_at:String){
}
fun show():String{
return user.created_at
}
}
- 网络接口
interface GetRequst_Interface {
@GET("authenticate?")
fun getCall(@Query("mobile") mobile:String,
@Query("username") username:String):Observable<Translation>
}
3.单例类,解决每次网络请求都需要创建一个retrofit对象的问题
class RequestInterfaceSingle private constructor(){
val request:GetRequst_Interface
init {
request = Retrofit.Builder()
.baseUrl("http://fivechess.tzchenyu.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
.create(GetRequst_Interface::class.java)
logIt()
}
companion object{
val REQUEST_INTERFACE_SINGLE:RequestInterfaceSingle by lazy(mode = LazyThreadSafetyMode.NONE){
RequestInterfaceSingle()
}
}
fun logIt(){
Log.d("bbbbbbb","调用了构造方法")
}
}
- viewmodel用于接收网络请求获取解析后的数据,将数据赋值给livedata。
class UseViewModel(countInit:String) :ViewModel(){
val counter: MutableLiveData<String>
get() = _counter
private val _counter = MutableLiveData<String>()/**livedata允许使用任意类型的值*/
init {
_counter.value = countInit
}
fun addIt(){
val observable = RequestInterfaceSingle.REQUEST_INTERFACE_SINGLE.request.getCall("12345678901","qq")
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<Translation> {
override fun onComplete() {
Log.d("aaaaaa","已获取服务器数据")
}
override fun onSubscribe(d: Disposable) {
Log.d("aaaaaa","已建立连接")
}
override fun onNext(t: Translation) {
_counter.value = t.show()
}
override fun onError(e: Throwable) {
Log.d("aaaaaa","发生错误"+e.toString())
}
})
}
}
- ViewModelFactory,由于viewmodel只能是ViewModelProviders.of才能实例化,所以,如果要viewmodel带有初始值,就需要借助viewModelFactory。
class UseViewModelFactory(private val countInit:String):ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return UseViewModel(countInit) as T
}
}
- Activity
class UseViewModelActivity : AppCompatActivity() {
lateinit var viewModel:UseViewModel
lateinit var binding: ActivityUseViewModelBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this,R.layout.activity_use_view_model)
viewModel = ViewModelProviders.of(this,UseViewModelFactory("获取时间")).get(UseViewModel::class.java)
binding.btnCount.setOnClickListener {
viewModel.addIt()
}
viewModel.counter.observe(this, Observer {
binding.viewmodel = viewModel
})
}
}
- XML
<?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>
<import type="com.fenririnc.aboutui.viewmodel.UseViewModel"></import>
<variable
name="viewmodel"
type="UseViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".UseViewModelActivity">
<TextView
android:id="@+id/tv_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
tools:text="0"
android:text="@{viewmodel.counter}"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加"
app:layout_constraintTop_toBottomOf="@id/tv_count"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>