美文网首页
Android中的数据绑定和mvvm模式

Android中的数据绑定和mvvm模式

作者: 我就是杨过 | 来源:发表于2018-06-15 14:36 被阅读0次

什么是MVVM

  • MVVM 是“Model-view-viewModel”的缩写
    - model 数据实体
    - view 对应于activity和xml布局 负责界面展示和与用户交互
    - viewModel 负责view和Model之间的交互 负责处理业务逻辑
  • 详细解释
    -ViewModel只做和业务逻辑和业务数据相关的事,不做任何和UI相关的事情,ViewModel 层不会持有任何控件的引用,更不会在ViewModel中通过UI控件的引用去做更新UI的事情。ViewModel就是专注于业务的逻辑处理,做的事情也都只是对数据的操作(这些数据绑定在相应的控件上会自动去更改UI
    - View层做的就是和UI相关的工作,我们只在XML、Activity和Fragment写View层的代码,View层不做和业务相关的事,也就是我们在Activity不写业务逻辑和业务数据相关的代码,更新UI通过数据绑定实现,尽量在ViewModel里面做(更新绑定的数据源即可),Activity要做的事就是初始化一些控件(如控件的颜色,添加RecyclerView的分割线),View层可以提供更新UI的接口(但是我们更倾向所有的UI元素都是通过数据来驱动更改UI),View层可以处理事件(但是我们更希望UI事件通过Command来绑定)。简单地说:View层不做任何业务逻辑、不涉及操作数据、不处理数据,UI和数据严格的分开。
    - Model层最大的特点是被赋予了数据获取的职责,与我们平常Model层只定义实体对象的行为截然不同。实例中,数据的获取、存储、数据状态变化都是Model层的任务。Model包括实体模型(Bean)、Retrofit的Service ,获取网络数据接口,本地存储(增删改查)接口,数据变化监听等。Model提供数据获取接口供ViewModel调用,经数据转换和操作并最终映射绑定到View层某个UI元素的属性上。
  • MVVM 模式流程示意图


    mvvm示意图.png

MVVM的一些特点

  • 双向数据绑定 在双向数据绑定模式中数据流是双向的,当业务上的数据发生改变之后,ui上的数据得到实时更新。当用户通过交互改变了数据的时候,数据的改变也能够自动更新到业务代码的数据中去。 在Android中数据绑定用的是DataDinding,谷歌官网推出的实现数据和ui绑定的框架。

DataBinding的基本使用

配置环境

  • 在build.gradle(app)中 配置 代码如下
android {
    compileSdkVersion 27
    buildToolsVersion '27.0.3'
    dataBinding {
        enabled = true
    }
              }

创建Java实体类(TODO )

DataBinding下的布局文件(TODO这个是重头戏 之后着重解释)

  • <layout> 作为整个布局的根节点。在编译之后会生成一个Binding类。命名规则是:单词首字母大写,移除下划线,并在最后添加上Binding。(如下面生成的类就是ActivityMainBinding)
  • 在布局中通过<variable>节点引入变量。变量名字自定。<type>标签写的是这个变量的具体类型。变量的引入是通过在activity中或者其他地方由布局文件生成的binding文件的set方法进行设置。(如果变量名字是“user”,在设置这个变量的时候,应该是(ActivityMainBinding binding.setUser(new User()))
  • 示例代码如下
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="user"
            type="mvvm.wangjing.com.mvvm.User.User" />
    </data>
    <RelativeLayout
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="mvvm.wangjing.com.mvvm.MainActivity">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:onClick="@{user.onItemClick}"
            android:text="@{`My name is `+  user.name+`  I'm   `+user.age+`  years old `}" />
    </RelativeLayout>
</layout>

在activity中 (代码入下) 引入布局

  • 用下面的setContentView() 代替activity中原本的setContentView()
ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("Looperjing", "20");
 viewDataBinding.setUser(user);

双向绑定的布局文件

  • 上面的实体类实现的是单向绑定 如果要实现双向绑定就要修改实体类这里有多重写法(TODO总结每种写法)

  • 这里要用到谷歌提供的几个类
    - ObservableField<> 定义泛型类,还有ObservableInt等基本数据类型的。
    - 作用是当实体类的数据发生改变的时候自动通知view刷新。通过变量的set()方法来设置值。通过get()方式来获取值。想改变一个字段,需要该字段的get方法添加上@Bindable注解,然后给该字段的set方法加上 notifyPropertyChanged([mvvm.wangjing.com.mvvm.BR.name]

  • 例子代码如下

public class User extends BaseObservable {

    public ObservableField<String> name = new ObservableField<>();
    public ObservableField<String> age = new ObservableField<>();

    public User(String pName, String pAge) {
        name.set(pName);
        age.set(pAge);
    }

    @Bindable
    public String getName() {
        return name.get();
    }

    public void setName(String name) {
        this.name.set(name);
        notifyPropertyChanged(mvvm.wangjing.com.mvvm.BR.name);
    }

    @Bindable
    public String getAge() {
        return age.get();
    }

    public void setAge(String age) {
        this.age.set(age);
    }

    public void onItemClick(View pView) {
        Toast.makeText(pView.getContext(), name.get(), Toast.LENGTH_SHORT).show();
        setName("June");
    }
}

Android中viewModel的使用

  • 这里只介绍viewModel的简单使用 结合上面的数据绑定 在布局文件中引入viewModel对象,就是mvvm模式
public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<User>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}
  • activity或者Fragment中的操作
public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}

相关文章

网友评论

      本文标题:Android中的数据绑定和mvvm模式

      本文链接:https://www.haomeiwen.com/subject/wxepeftx.html