一、MVVM架构的优缺点
优点:
1.数据双向绑定,能很好的保证数据的一致性
2.UI与逻辑部分解耦更加完全
缺点:
1.使用DataBinding,导致内存开销大
2.xml布局文件与数据绑定,降低布局的可重用性
3.不宜进行bug跟踪调试
二、实现步骤
1.在gradle中打开DataBinding
//打开dataBinding工具
dataBinding {
enabled = true
}
2.新建实体类,即modle类
import androidx.databinding.ObservableField;
public class UserBean {
//被观察的属性(注意:属性必须是public修饰,DataBinding规定)
public ObservableField<String> name = new ObservableField<>();
public ObservableField<String> pwd = new ObservableField<>();
}
3.修改xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--指定绑定的ViewModel-->
<data>
<variable
name="loginViewModel"
type="com.wkr.mvvmproject.vm.LoginViewModel" />
</data>
<!--正常的布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:addTextChangedListener="@{loginViewModel.nameInputListener}"
android:hint="用户名"
android:text="@{loginViewModel.userBean.name}" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:addTextChangedListener="@{loginViewModel.pwdInputListener}"
android:hint="密码"
android:text="@{loginViewModel.userBean.pwd}" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:onClick="@{loginViewModel.onClickListener}"
android:text="登录" />
</LinearLayout>
</layout>
4.新建ViewModel类
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import com.wkr.mvvmproject.bean.UserBean;
import com.wkr.mvvmproject.databinding.ActivityMainBinding;
public class LoginViewModel {
public UserBean userBean;
public LoginViewModel(ActivityMainBinding viewDataBinding) {
userBean = new UserBean();
//将ViewModel和View进行绑定,通过DataBanding工具
viewDataBinding.setLoginViewModel(this);
}
public TextWatcher nameInputListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//view层接收用户输入,改变model层的javabean属性
userBean.name.set(String.valueOf(s));
}
@Override
public void afterTextChanged(Editable s) {
}
};
public TextWatcher pwdInputListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
userBean.pwd.set(String.valueOf(s));
}
@Override
public void afterTextChanged(Editable s) {
}
};
public View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("TAG", "NAME======>" + userBean.name.get());
Log.e("TAG", "pwd======>" + userBean.pwd.get());
userBean.name.set("张三");
}
};
}
4.在Activity中将布局通过DataBinding进行绑定
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//1、必须先Rebuild;2.绑定代码
ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
new LoginViewModel(viewDataBinding);
}
}