Android MVVM最简易举例(ViewModel&LiveData)

前言:

viewModel是什么?有什么作用?

viewModel介于View(视图)和Model(模型数据)之间的这样一个东西,它起到了桥梁的作用,使得视图和数据既能够分离开,也能够保持通信。

MVVM 的本质是 数据驱动,把解耦做的更彻底,viewModel不持有view 。

View 产生事件,使用 ViewModel进行逻辑处理后,通知Model更新数据,Model把更新的数据给ViewModel,ViewModel自动通知View更新界面而不是主动调用View的方法

MVVM  = Data + View + ViewModel

Data = 数据(本场景点击一次 视为接口返回+1的数据)

View = TestMVVMActivity 

ViewModel = TestViewModel

场景举例:  一个按钮 点击后次数累加显示

0.首先导入依赖: 在build.gradle 文件中

dependencies {
    ... ... 

    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'//ViewModelProviders
}

1.创建Activity:TestMVVMActivity  

class TestMVVMActivity : FragmentActivity() {

    var count = 0

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

        var mViewModel = ViewModelProviders.of(this).get(TestViewModel::class.java)
        mViewModel.name.observe(this, Observer {
            //每次调用mViewModel.setName() 时 会执行这里
            test_textview.text = "当前次数:$it"
        })
        test_textview.setOnClickListener {
            mViewModel.setName("" + count++)
        }


    }

}

2.XML代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".test.TestMVVMActivity">

    <TextView
        android:id="@+id/test_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#0000ff"
        android:padding="40dp"
        android:text="当前次数:0  (点击增加次数)"
        android:textColor="#ffffff"
        android:textSize="30sp" />

</LinearLayout>

3.TestViewModel:

class TestViewModel extends ViewModel {

    MutableLiveData<String> name = new MutableLiveData();

    public MutableLiveData<String> getName() {
        return name;
    }

    public void setName(String name) {
        this.name.postValue(name);  // 对应响应 getName 的 observe回调
    }

}

4.ViewModelFactory (正常情况下不需要用它,假如要用的话代码如下):

public class ViewModelFactory implements ViewModelProvider.Factory {

    private TestViewModel mViewModel;

    public ViewModelFactory(TestViewModel viewModel) {
        this.mViewModel = viewModel;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        if (modelClass.isAssignableFrom(TestViewModel .class)) {
            return (T) mViewModel;
        }
        throw new IllegalArgumentException("Unknown class name");
    }

}

核心思想:

UI界面的显示  与  ViewModel的数据变化 形成了一个显著的 观察者模式     

当ViewModel的数据发生变化时,UI自动更新

核心实现是:    

TestViewModel 中的  MutableLiveData 变量     // 可被观察数据

以及  setName方法中的 postValue()    //数据改变时发通知

以及  TestMVVMActivity中的 mViewModel.name.observe(this, Observer {})      //数据变化时需响应的监听

实际使用场景中:

点击事件中的 mViewModel.setName("" + count++)   就相当于 接口请求后 给 model 赋值的 过程,

这时候 因为接口数据返回,而改变数据 改变UI

注意:

        当出现 Cannot create an instance of class TestViewModel class 错误时


        在ViewModelProvider构造方法中加Application参数  

        或使用 ViewModelProvider.AndroidViewModelFactory 类创建 TestViewModel 均无法解决该异常                     

        正确的解决方案是新增 自定义的 ViewModelFactory 参数

     val mViewModel = ViewModelProvider(this, ViewModelFactory(TestViewModel()) )[TestViewModel::class.java]

为什么没有用DataBinding?

MVVM的缺点(Databinding的缺点):

   1.数据绑定增加Bug调试难度
   2.对于复杂的页面,model也会很大,虽然使用方便了也很容易保证了数据的一致性,但长期持有,不利于释放内存
   3.数据双向绑定不利于View重用

深海个人不建议使用这个弊大于利的笨重框架

如果您有好的建议或者错误纠正,欢迎在评论区一起探讨

如果深海写的东西对您有用,请您给该博客点个赞吧

大家的支持就是深海继续写博客的动力,谢过各位

猜你喜欢

转载自blog.csdn.net/qq_39731011/article/details/115765191
今日推荐