MVVM 基本的用法

MVVM 与 MVP 基本类似,将presenter 换为 ViewModel, 用 data-binding 连接 View 和 ViewModel,进行双向交互。当 View 修改时,会反映到 ViewModel,ViewModel 有变化,会影响到 View,它们之间互相影响,而不像 MVP ,只是 View 被动的接受 Presenter 的调用。

关于 data-binding的知识,官网发布了 Data Binding Library 库。
首先在 build.gradle中:

android {
   ...
    dataBinding{
        enabled = true
    }
}

Xml 需要引入 data 标签,让 ViewModel 可以和 View 进行双向交互。

<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="viewModel" type="com.example.mvvm.ViewModel"/>
    </data>

    <RelativeLayout
       ..

        <EditText
            android:id="@+id/ex_name"
            ..
            android:hint="姓名"/>

        <Button
            android:id="@+id/btn"
           ..
            android:onClick="@{viewModel.onClick}"//1
            android:text="查询"/>
        <TextView
            android:id="@+id/tv_result"
          ..
            android:text=""/>
    </RelativeLayout>
</layout>

ViewModel

public class ViewModel implements OnSearchListener{

    private static final String TAG = "ViewModel";

    private ActivityMainBinding mActivityMainBinding;
    private User mUser;

    public ViewModel(ActivityMainBinding activityMainBinding) {
        mActivityMainBinding = activityMainBinding;
        mUser = new User(this);
//      mActivityMainBinding.setModel(mUser);
    }

    /**
     * 在 XML 中Button 的点击方法
     * @param view
     */
    public void onClick(View view) {
        Log.d(TAG, "onSearch: ");
        String name = mActivityMainBinding.exName.getText().toString();
        if(!TextUtils.isEmpty(name)){
            mUser.getResult(name);
        }
    }

    @Override
    public void onSuccess(String name) {

        mUser.setName(name);
        mActivityMainBinding.tvResult.setText(mUser.getName());
    }

    @Override
    public void onError() {
//      mUser.setName("失败");
        mActivityMainBinding.tvResult.setText("失败");

    }
}

Activity

ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
//绑定 viewModel
binding.setViewModel(new ViewModel(binding));

当 xml 完成后,会生成 xml 文件名 + Binding 的类。
比如:activity_main–> ActivityMainBinding.
这个类可以将 data 标签中类 和 xml 控件绑定在一起。

ViewModel

public class ViewModel implements OnSearchListener{

    private static final String TAG = "ViewModel";
    private ActivityMainBinding mActivityMainBinding;
    private User mUser;

    public ViewModel(ActivityMainBinding activityMainBinding) {
        mActivityMainBinding = activityMainBinding;
        mUser = new User(this);
//      mActivityMainBinding.setModel(mUser);
    }

    /**
     * 在 XML 中Button 的点击方法
     * @param view
     */
    public void onClick(View view) {
        Log.d(TAG, "onSearch: ");
        String name = mActivityMainBinding.exName.getText().toString();
        if(!TextUtils.isEmpty(name)){
            mUser.getResult(name);
        }
    }

    @Override
    public void onSuccess(String name) {

        mUser.setName(name);
        mActivityMainBinding.tvResult.setText(mUser.getName());
    }

    @Override
    public void onError() {
//      mUser.setName("失败");
        mActivityMainBinding.tvResult.setText("失败");

    }
}

Model 做匹配工作。

然而 data-binding 的双向交互还没有体现出来,就像 RecyclerView 和 Adapter。当数据变化时,提醒 视图更新。

提醒更新方式有两种:在Bean 类中操作
1:需要在 data 标签中声明,在控件中引用属性。

 <data>
     ..
        <variable name="model" type="com.example.mvvm.User"/>
    </data>
..
 <TextView
           ...
            android:text="@{model.name}"/>

2.进行绑定

        ...
        mActivityMainBinding.setModel(mUser);

3.添加响应
(1)需要继承 BaseObservable,在get方法添加注解 @Bindable,在对应的 set 方法中,notifyPropertyChanged(BR.‘属性名’);这样调用用 set 方法时,View 中的数据就会自动更新。

public class User extends BaseObservable{

private static final String TAG = "ViewModel";

private String name = "fdsf";

private OnSearchListener mOnSearchListener;
public User(OnSearchListener onSearchListener) {
    mOnSearchListener = onSearchListener;
}

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

public void setName(String nsame) {
    this.name = nsame;
    notifyPropertyChanged(BR.name);
}

public void  getResult(String name){

    this.name= name;

    if(name.equals(this.name)){
        mOnSearchListener.onSuccess(name);
    }else{
        mOnSearchListener.onError();
    }
}
2)使用 Observablexxx 包装属性
    使用时:需要 属性名.set(),属性名.get()

public ObservableField name = new ObservableField<>();
this.name.set(name);
String s = this.name.get();
“`

这是一些基本的知识点,但还有一些疑惑,在添加自动更新后,Model 与 View 之间也有直接联系,这样不符合 MVVP 模式的设计原则。
源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值