DataBinding做了什么之前分析过了,DataBinding跟MVVM并没有什么直接的联系,在MVC、MVP中同样可以使用,只是这里的MVVM是用DataBinding去实现的。
以简单登录页面为例的小Demo:
- 首先使用DataBinding要在app的build.gradle中配置:
apply plugin: 'com.android.application'
android {
...
// 添加DataBinding依赖
dataBinding{
enabled = true
}
}
dependencies {
...
}
- 新建Model:UserInfo
public class UserInfo {
public ObservableField<String> username = new ObservableField<>();
public ObservableField<String> password = new ObservableField<>();
}
Model可以用普通的写法,定义两个变量然后提供setter、getter,这里说过了。
- 既然是MVVM,那一定要有一个VM了,VM是View和Model的桥梁,里面会做一些监听和逻辑处理:
public class LoginViewModel {
public UserInfo userInfo;
public LoginViewModel() {
userInfo = new UserInfo();
//TODO, 这里需要和View层建立连接
}
public TextWatcher usernameInputListener = 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) {
userInfo.username.set(String.valueOf(s));
}
@Override
public void afterTextChanged(Editable s) {
}
};
public TextWatcher passwordInputListener = 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) {
userInfo.password.set(String.valueOf(s));
}
@Override
public void afterTextChanged(Editable s) {
}
};
public View.OnClickListener loginClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
if ("123".equals(userInfo.username.get()) && "456".equals(userInfo.password.get())){
Log.e("haha", "登录成功");
}else {
Log.e("haha", "登录失败");
}
}
}).start();
}
};
}
- 然后就是xml布局文件的设置,这里说的是直接绑定Model,而在MVVM里需要绑定的是VM,把要显示的内容、监听等等都绑定给VM,对应上面的LoginViewModel中的实现:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="loginViewModel"
type="com.yu.mvvm.viewModel.LoginViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:addTextChangedListener="@{loginViewModel.usernameInputListener}"
android:text="@={loginViewModel.userInfo.username}" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:addTextChangedListener="@{loginViewModel.passwordInputListener}"
android:text="@={loginViewModel.userInfo.password}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:onClick="@{loginViewModel.loginClickListener}"
android:text="登录" />
</LinearLayout>
</layout>
- Activity中设置布局:
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
// 与VM建立连接
...
}
}
关于ActivityLoginBinding
,还是看这里。
- 上面几步完成之后,发现VM并没有与View建立连接,所以在Activity的onCreate里:
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
// 与VM建立连接
new LoginViewModel(binding);
}
}
然后修改LoginViewModel的构造函数:
public class LoginViewModel {
...
public LoginViewModel(ActivityLoginBinding binding) {
userInfo = new UserInfo();
binding.setLoginViewModel(this);
}
...
}
哦了, 记得布局写完Databinding的配置之后,rebuild一下再用ActivityLoginBinding
这个类,不然没有这个类哦,这个类哪来的?还是看这里。
哦了!
项目地址