MVVM的使用

 

 

使用DataBinding需要三个步骤:

1、启用DataBinding

 2、修改布局文件为DataBinding布局

把传统的布局替换为dataBinding布局:在外层布局按住Ctrl+回车会提示是否转化成dataBinding布局,直接转化:

 3、数据绑定:替换setContentView: 经过上述步骤,系统会自动生成ActivityMainBinding类,类名是布局文件名+Binding,布局文件首字母大写

<?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="account"
            type="com.example.myapplication.databinding.MyAccount" />
        <variable
            name="activity"
            type="com.example.myapplication.MainActivity" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{account.name + '|' + account.level}"
            android:textSize="30dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="30dp" />

        <Button
            android:id="@+id/bt"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:text="加1"
            android:textSize="20dp"
            android:layout_gravity="center_horizontal"
            android:onClick="@{activity.onClick}"
            android:layout_marginTop="40dp" />
    </LinearLayout>
</layout>
public class MainActivity extends AppCompatActivity {
    ActivityMainBinding binding;
    MyAccount mAccount;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
//        binding.textView.setText("你好");
        mAccount = new MyAccount();
        mAccount.setLevel("1");
        mAccount.setName("dongjie");
        binding.setAccount(mAccount);
        binding.setActivity(this);
    }

    public void onClick(View v) {
        Toast.makeText(this, "点击", Toast.LENGTH_LONG).show();
//        binding.setAccount(mAccount);
//        binding.textView.setText("aaaaa");
        mAccount = new MyAccount();
        mAccount.setLevel("2");
        mAccount.setName("dongjiejie");
        binding.setAccount(mAccount);
    }
}

经过上述步骤,修改数据就可以自动更新到界面上了。

上面的方法还可以优化,当数据变化的时候,自动更新界面数据:

1、继承BaseObservable

2、get方法添加@Bindable

3、set方法添加notifyPropertyChanged(BR.name);

package com.example.myapplication.databinding;

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;

import com.example.myapplication.BR;

public class MyAccount extends BaseObservable {
    String name;
    String level;

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

    public void setName(String name) {
        this.name = name;
        // 当name发生变化的时候,更新界面数据, BR是DataBinding生成的,类似于R
        notifyPropertyChanged(BR.name);
    }

    @Bindable
    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
        notifyPropertyChanged(BR.level);
    }
}

经过上述步骤,上面的onClick方法就可以这么写:改变数据源以后会自动同步到界面上

    public void onClick(View v) {
        mAccount.setLevel("2");
        mAccount.setName("dongjiejie");
    }

到目前为止都是单向绑定,数据更新以后会直接同步到界面上,在@后面加等号就是双向绑定了,一般用的比较多得是输入框

MVVM实现需求需要以下几个步骤:

 下面给一个完整的demo: 

SecondActivity.java 和activity_second.xml

package com.example.myapplication.databinding2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import android.os.Bundle;

import com.example.myapplication.R;
import com.example.myapplication.databinding.ActivitySecondBinding;

public class SecondActivity extends AppCompatActivity {
    ActivitySecondBinding mBinding;
    MVVMViewModel mVVMViewModel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_second);
        mVVMViewModel = new MVVMViewModel(getApplication(), mBinding);
        // 在xml里的变量都得初始化
        mBinding.setViewModel(mVVMViewModel);

    }
}
<?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>
        <!-- 声明MVVMViewModel,在activity中初始化 -->
        <variable
            name="viewModel"
            type="com.example.myapplication.databinding2.MVVMViewModel" />
        <variable
            name="activity"
            type="com.example.myapplication.MainActivity" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <EditText
            android:id="@+id/edit_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:textSize="30dp"
            android:text="@={viewModel.inputStr}"
            android:layout_marginTop="30dp" />

        <!--注意设置点击事件,不能带括号,只写方法名-->
        <Button
            android:id="@+id/bt"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:text="点击"
            android:textSize="20dp"
            android:layout_gravity="center_horizontal"
            android:onClick="@{viewModel.getData}"
            android:layout_marginTop="40dp" />

        <TextView
            android:id="@+id/text_view"
            android:textSize="20dp"
            android:textColor="#000"
            android:layout_marginTop="30dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="match_parent"
            android:text="@{viewModel.result}"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</layout>

MVVMViewModel.java

这一层相当于MVP的Presenter,处理逻辑,它里面调用Model层来请求数据,然后通过DataBinding来设置到界面上,如果遇到请求权限等操作,此层可以持有Activity的对象,或者用EventBus也可以, 不过一般不要这么做,一般用LiveData+ViewModel的方式来做。

package com.example.myapplication.databinding2;

import android.app.Application;
import android.view.View;

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;

import com.example.myapplication.BR;
import com.example.myapplication.databinding.ActivitySecondBinding;

// MVVMViewModel相当于MVP的Presenter,处理业务逻辑
public class MVVMViewModel extends BaseObservable {
    Application application;
    ActivitySecondBinding mBinding;
    String result;
    String inputStr;
    MVVMModel mModel;
    public MVVMViewModel(Application application) {
        this.application = application;
        mModel = new MVVMModel();
    }

    public MVVMViewModel(Application application, ActivitySecondBinding binding) {
        this(application);
        mBinding = binding;
    }

    public void getData(View v) {
//        String editStr = mBinding.editView.getText().toString();
//        String ret = mModel.getScreenData(editStr);
//        setResult(ret);   // 必须调用setResult才能更新

        // 因为inputStr和控件是双向绑定,所以输入的时候inputStr是最新值,这样就不用传ActivitySecondBinding参数
        String ret = mModel.getScreenData(inputStr);
        setResult(ret);
    }

    @Bindable
    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
        notifyPropertyChanged(BR.result);
    }

    @Bindable
    public String getInputStr() {
        return inputStr;
    }

    public void setInputStr(String inputStr) {
        this.inputStr = inputStr;
        notifyPropertyChanged(BR.inputStr);
    }
}

MVVMModel.java     

这里模拟请求数据,一般是通过回调返回数据给MVVMViewModel的,这里为了简单写了同步方法

package com.example.myapplication.databinding2;

import com.example.myapplication.databinding.ActivitySecondBinding;

public class MVVMModel {
    public MVVMModel() {
    }

    public String getScreenData(String inputStr) {
        String str = "请求参数:" + inputStr + "\n请求数据:谢谢谢谢谢寻寻寻寻寻";
        return str;
    }
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值