本文默认读者有必定的Android开发经验,对Android Annotations和DataBinding技术也有了简单的了解。php
文章经过三种不一样方式代码的对比,最后总结说明为何要使用DataBinding的技术。前端
三种不一样方式代码须要实现的功能是在登陆界面里,经过监听用户名和密码输入框的文本变化,动态控制登陆按钮点击状态。java
采用普通方式编写代码,能够发现会有不少的多余地方,大部分都是重复的工做:android
findViewById(...)
addTextChangedListener(...)
setOnClickListener(...)
xml文件有两个EditText
和一个Button
,比较简单,这里就不贴代码了,只贴出Activity代码:angularjs
public class LoginNormalActivity extends AppCompatActivity {
private EditText nameEdit;
private EditText pwdEdit;
private Button loginBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
//实例化view
nameEdit = (EditText) findViewById(R.id.login_name_edit);
pwdEdit = (EditText) findViewById(R.id.login_pwd_edit);
loginBtn = (Button) findViewById(R.id.login_btn);
//添加文本变化监听
OnTextChangeListener textChangeListener = new OnTextChangeListener();
nameEdit.addTextChangedListener(textChangeListener);
pwdEdit.addTextChangedListener(textChangeListener);
//登陆按钮点击事件监听
loginBtn.setOnClickListener(v -> Toast.makeText(this, "click login!", Toast.LENGTH_SHORT).show());
updateLoginEnable();
}
/** * 更新登陆按钮的状态 */
private void updateLoginEnable() {
loginBtn.setEnabled(!(TextUtils.isEmpty(nameEdit.getText()) || TextUtils.isEmpty(pwdEdit.getText())));
}
/** * 文本变化监听Listener */
private class OnTextChangeListener implements TextWatcher {
...
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//在文本变化结束后去更新
updateLoginEnable();
}
}
}复制代码
注解方式编写代码,让你专一于真正重要的地方,使代码更加精简:ide
@ViewById
@Click
@AfterTextChange
解决不少重复工做xml文件有两个EditText
和一个Button
,比较简单,一样也就不贴代码了,只贴出Activity代码:工具
@EActivity(R.layout.login_activity)
public class LoginAnnotationActivity extends AppCompatActivity {
//实例化view
@ViewById(R.id.login_name_edit)
protected EditText nameEdit;
@ViewById(R.id.login_pwd_edit)
protected EditText pwdEdit;
@ViewById(R.id.login_btn)
protected Button loginBtn;
@AfterViews
protected void initView() {
updateLoginEnable();
}
/** * 更新登陆按钮的状态 */
private void updateLoginEnable() {
loginBtn.setEnabled(!(TextUtils.isEmpty(nameEdit.getText()) || TextUtils.isEmpty(pwdEdit.getText())));
}
/** * 登陆点击回调 */
@Click(R.id.login_btn)
protected void login(View view) {
Toast.makeText(this, "click login!", Toast.LENGTH_SHORT).show();
}
//添加文本变化监听
@AfterTextChange({R.id.login_pwd_edit, R.id.login_name_edit})
protected void afterTextChange(TextView tv, Editable text) {
//在文本变化结束后去更新
updateLoginEnable();
}
}复制代码
绑定方式:去除了冗余代码的基础上对数据和UI层进行解耦 this
android:text="@={...}"
将数据双向绑定到UI中android:enabled="@{...}"
控制按钮状态android:onClick="@{...}"
直接处理用户操做事件首先xml文件代码:spa
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="loginViewHelper" type="com.free.fastmvpdemo.login.LoginViewHelper" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="20dp" android:paddingRight="20dp">
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:hint="@string/account_hint" android:text="@={loginViewHelper.name}" />
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:hint="@string/pwd_hint" android:text="@={loginViewHelper.pwd}" />
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:enabled="@{loginViewHelper.canLogin(loginViewHelper.name,loginViewHelper.pwd)}" android:onClick="@{loginViewHelper.login}" android:text="@string/login" />
</LinearLayout>
</layout>复制代码
上面xml代码咱们能够看出,数据绑定规则已经放在里面了,其实java代码的只须要处理业务相关的逻辑就行了,很是的清晰,而后Activity和辅助Helper代码:双向绑定
public class LoginActivity extends AppCompatActivity {
//DataBinding自动生成的类,命名规则是取xml文件名加Binding结尾
LoginActivityBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//初始化data bind,并设置Helper实例
binding = DataBindingUtil.setContentView(this, R.layout.login_activity);
binding.setLoginViewHelper(new LoginViewHelper());
}
}
public class LoginViewHelper {
//监听属性
public ObservableField<String> name = new ObservableField<>();
public ObservableField<String> pwd = new ObservableField<>();
/** * 登陆点击回调 */
public void login(View view) {
Toast.makeText(view.getContext(), "click login!", Toast.LENGTH_SHORT).show();
}
/** * 是否能够登陆 */
public boolean canLogin(String name, String pwd) {
return !(TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd));
}
}复制代码
最后吐槽一下:目前Android的绑定和前端的angularjs相比还有不小的差距,尤为是在双向绑定这一块,另外Android studio对DataBinding的报错和代码自动生成这方面的支持也不太友好。固然这只是现状,会慢慢变好的。