上一篇介紹了mvp的實現思路,這裏介紹android原生自帶的數據綁定框架的使用。對於的官方工程也是放在mvp簡介的介紹頁面裏的,html
對應的官方Data Binding示例地址爲:https://github.com/googlesamples/android-architecture/tree/todo-databinding/java
也能夠查看官方關於Data Binding 庫的說明:http://developer.android.com/tools/data-binding/guide.html#data_objectsandroid
安卓的實現一個界面,正常的作法是新建一個Activity類,新建一個layout文件,在Activity的setContentView(R.layout.xxxxx);把Activity類與layout佈局綁定,而後使用findViewById(R.id.xxxx)找到指定控件,而後對控件作相應的操做,對於列表控件顯示也是大概相同的流程,都是View view = LayoutInflater.from(Context()).inflate(R.layout.xxx, viewGroup, false);找到父容器控件後再View.findViewById(R.id.xxx)找到具體的控件,對其進行相應的設置。git
Data Binding 庫能實現的功能是在layout佈局文件定義時,就指定了數據與控件的綁定和界面事件的處理。省去了必須findViewById的麻煩,以及更好的作到數據與界面的分離。github
1.控件與數據的綁定,在layout裏指定控件的一些屬性怎樣與指定的數據綁定app
android:text="@{task.title}"框架
代替以往的。((EditText)findViewById(R.id.add_task_title)).setText(task.getTitle());ide
<EditText android:id="@+id/add_task_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/title_hint" android:text="@{task.title}" android:singleLine="true" android:textAppearance="@style/TextAppearance.AppCompat.Title" />
android:visibility="@{stats.showStatus ? View.VISIBLE : View.GONE}"工具
代替以往的findViewById(R.id.add_task_title).setVisibility(task.showStatus?View.VISIBLE: View.GONE);佈局
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@{stats.status}" android:textAppearance="?android:attr/textAppearanceMedium" android:visibility="@{stats.showStatus ? View.VISIBLE : View.GONE}" />
android:background="@{task.isCompleted?@drawable/list_completed_touch_feedback: @drawable/touch_feedback}"
代替以往的 View.setBackgroundResource(task.isCompleted?R.drawable.xxx: R.drawable/xx);
<LinearLayout android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:background="@{task.isCompleted ? @drawable/list_completed_touch_feedback : @drawable/touch_feedback}" android:orientation="horizontal" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/list_item_padding" android:paddingTop="@dimen/list_item_padding" android:onClick="@{() -> actionHandler.taskClicked(task)}">
2.控件與方法的綁定,在layout裏指定控件的一些點擊接口或其餘回調接口怎樣與對應的方法綁定。
android:onClick="@{() -> actionHandler.taskClicked(task)}"
代替View.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
<LinearLayout android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:background="@{task.isCompleted ? @drawable/list_completed_touch_feedback : @drawable/touch_feedback}" android:orientation="horizontal" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/list_item_padding" android:paddingTop="@dimen/list_item_padding" android:onClick="@{() -> actionHandler.taskClicked(task)}">
如何使用Data Binding 庫
1.開發環境:
compileSdkVersion 25
buildToolsVersion "25.0.2"
classpath 'com.android.tools.build:gradle:2.3.0'
並不須要根項目聲明apt插件,
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
也不須要在模塊裏
apply plugin: 'com.neenbedankt.android-apt'
只須要在用到的模塊下加入下面語句。
dataBinding { enabled = true }
2.1用於與界面綁定數據的java
新建Java類,並繼承 android.databinding.BaseObservable,把須要在layout佈局裏引用的方法,加上@Bindable註解或@BindingAdapter, 使用@Bindable註解過的方法能夠直接使用在xml佈局裏,以下面定義的getName()方法,能夠在layout裏這樣使用
android:text='@{"name:"+company.getName()}'
public class Company extends BaseObservable{ ......省略若干代碼 @BindingAdapter({"bind:imageUrl", "bind:error"}) public static void setIcon(ImageView view, String url, Drawable error) { Glide.with(view.getContext()).load(url).error(error).into(view); } @Bindable public String getName() { return name; } ......省略若干代碼 }
若是layout裏須要用到一些工具類裏的靜態方法,不須要繼承BaseObservable,也不須要在方法前增長註解。
public class DateUtil{ ......省略若干代碼 public static String getTime(long time) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); return sdf.format(time); } ......省略若干代碼 }
2.2 用於與控件綁定事件的類,不須要使用註解。像普通的java類同樣定義便可。
public class ActionHandler { private Context mContext; public ActionHandler(Context context) { this.mContext = context; } public void showTextDialog(String text) { new AlertDialog.Builder(mContext).setTitle("detail") .setMessage(text).create().show(); } }
在layout裏便可調用:android:onClick="@{(tv)->actionHandler.showTextDialog(company.toString())}"
3.定義layout佈局
不使用Data Binding 庫的layout佈局以下。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.databindtest.MainActivity">
......省略若干代碼
</LinearLayout>
使用Data Binding庫須要以layout爲根標籤,並加入一個data子標籤,
data標籤裏經常使用到的有variable和import標籤,
variable標籤引入的是一個須要在java代碼裏動態設置的對象,type字段是Java類的導入,至關於代碼裏的import android.databinding.BaseObservable;
name字段至關於變量名稱。
當data標籤裏有以下的一段代碼時,
<variable name="company" type="com.example.databindtest.Company" />
當自動生成的Data Binding對象會生成一個setCompany(com.example.databindtest.Company c)的方法
import 標籤通常是聲明須要引用一些工具類裏的裏的靜態方法。
和一些用到的類型,若是app:error="@{@drawable/ic_launcher'}" 就須要先聲明Drawable。
不管是綁定數據仍是事件方法,都是找到對象而後調用相應的get方法或事件方法。
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="company" type="com.example.databindtest.Company" /> <variable name="actionHandler" type="com.example.databindtest.ActionHandler" /> <import type="android.graphics.drawable.Drawable" /> <import type="com.example.databindtest.DateUtil" /> </data> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/company_item_root_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/cardview_dark_background" android:padding="8dp"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.CardView android:id="@+id/cv_wrap" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="8dp"> <ImageView android:id="@+id/iv_icon" android:layout_width="80dp" android:layout_height="80dp" android:minHeight="80dp" android:minWidth="80dp" android:layout_centerVertical="true" android:onClick="@{(tv) -> actionHandler.showImageDialog(company.getIcon())}" app:error="@{@drawable/ic_launcher'}" app:imageUrl="@{company.getIcon()}" /> </android.support.v7.widget.CardView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_toRightOf="@id/cv_wrap" android:orientation="vertical"> </LinearLayout> </RelativeLayout> </android.support.v7.widget.CardView> </FrameLayout> </layout>
作完上面的工做後,已經準備好了數據實體對象和layout佈局,若是這時候使用了android studio的Build->Make Module 'xxx'的編譯某個模塊的功能,若是沒有編譯出錯,能夠看到在相應的臨時編譯生成了對應的xxxBinding文件,以下圖所示
只須要在Activity裏簡單的調用幾句,就能夠實現數據自動填充到View,而且綁定控件的事件處理方法。
調用 Binding.setCompany(mCompany);會自動把數據填充到View上。
package com.example.databindtest; import android.content.Context; import android.databinding.DataBindingUtil; import android.support.annotation.Nullable; import android.support.v4.app.DialogFragment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import com.example.databindtest.databinding.CompanyItemLayoutBinding; import java.util.List; public class MainActivity extends AppCompatActivity { private Company mCompany; CompanyItemLayoutBinding mBinding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBinding = DataBindingUtil.bind(findViewById(R.id.company_item_root_layout)); mCompany = Company.getCompanyList().get(0); mBinding.setActionHandler(new ActionHandler(this)); mBinding.setCompany(mCompany); initView(); } //......省略若干代碼 public void setting(View view) { mCompany.setIcon(((EditText)findViewById(R.id.et_company_icon_path)).getText().toString()); mCompany.setName(((EditText)findViewById(R.id.et_company_name)).getText().toString()); mCompany.setInfo(((EditText)findViewById(R.id.et_company_info)).getText().toString()); mBinding.setCompany(mCompany); } //......省略若干代碼 }
完整代碼請查看