本文默認讀者有必定的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的報錯和代碼自動生成這方面的支持也不太友好。固然這只是現狀,會慢慢變好的。