Project
https://github.com/awonwon/gdgk-
databinding-sample
DataBinding
@GDG Kaohsiung
我是誰?
awonwon
25sprout Android
HITCON GIRLS
Android Studio 2.0 ^^?
What is Data Binding?
TextView
String show = "Hello"
DataBinding
Layout Activity
What is Data Binding?
Hello
TextView
String show = "Hello"
binding.set (show);
DataBinding
Layout Activity
What is Data Binding?
GGWP
TextView
Show="GGWP";
DataBinding
Layout Activity
Layout Activity
Binding With POJO
Name
TextView
DataBinding
Tel
TextView
Tel
TextView
User user = new User();
binding.set (user);
Clean Code
Zero Reflection
Official Library
MMVM
YEAH
main_layout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/
android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
<TextView
android:id="@+id/view_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
< TextView …
</LinearLayout>
LinearLayout
{id}
{name}
{level}
{exp}
MainActivity
LinearLayout
{id}
{name}
{level}
{exp}
private TextView idView, nameView, levelView, expView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
findViews();
User user = new User("8591", " ", "5",
"2000");
idView.setText(user.id);
nameView.setText(user.name);
levelView.setText("LV." + user.level);
expView.setText(user.exp);
}
private void findViews(){
idView = (TextView) findViewById(R.id.view_id);
nameView = (TextView) findViewById(R.id.view_name);
levelView = (TextView) findViewById(R.id.view_level);
expView = (TextView) findViewById(R.id.view_exp);
}
MainActivity
LinearLayout
8591
LV.5
2000
private TextView idView, nameView, levelView, expView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
findViews();
User user = new User("8591", " ", "5","2000"
idView.setText(user.id);
nameView.setText(user.name);
levelView.setText("LV." + user.level);
expView.setText(user.exp);
}
private void findViews(){
idView = (TextView) findViewById(R.id.view_id);
nameView = (TextView) findViewById(R.id.view_name);
levelView = (TextView) findViewById(R.id.view_level);
expView = (TextView) findViewById(R.id.view_exp);
}
DataBinding
Build.gradle
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.sprout.give"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
dataBinding {
enabled = true
}
}
DataBinding
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
<TextView
android:id="@+id/view_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
< TextView …
</LinearLayout>
</layout>
main_layout
LinearLayout
{id}
{name}
{level}
{exp}
Root View <Layout>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class="MainActivityDataBinding">
<import type="com.awonwon.User"/>
<variable
name="user"
type="user"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
<TextView
android:id="@+id/view_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
< TextView …
</LinearLayout>
</layout>
main_layout
LinearLayout
{id}
{name}
{level}
{exp}
& Import Class
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class="MainActivityDataBinding">
<import type="com.awonwon.User"/>
<variable
name="user"
type="user"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.id}"/>
<TextView
android:id="@+id/view_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.name}"/>
< TextView …
</LinearLayout>
</layout>
main_layout
LinearLayout
{user.id}
{user.name}
{user.level}
{user.exp}
binding @{value}
MainActivity
LinearLayout
{user.id}
{user.name}
{user.level}
{user.exp}
public class MainAcivity extends AppCompatActivity{
private TextView idView, nameView, levelView, expView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
findViews();
User user = new User("8591", " ", "5", "2000");
idView.setText(user.id);
nameView.setText(user.name);
levelView.setText("LV." + user.level);
expView.setText(user.exp);
}
private void findViews(){
idView = (TextView) findViewById(R.id.view_id);
nameView = (TextView) findViewById(R.id.view_name);
levelView = (TextView) findViewById(R.id.view_level);
expView = (TextView) findViewById(R.id.view_exp);
}
}
LinearLayout
8591
LV.5
2000
MainActivity public class MainAcivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityDataBinding binding =
DataBindingUtil.setContentView(
this, R.layout.main_layout);
User user = new User("8591", " ", "5", "2000");
binding.setUser(user);
}
BindingClass & Value
findView
。:.゚ (*´∀`)ノ゚.:。
Layout
View
DataBinding
Class
Layout
Data Binding
BindingClass
BindinClass
tag
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{"Lv."+user.level}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{"Lv."+user.level}"/>
"Lv." + user.level
=> LV.5
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:tag="binding_1"/>
DataBinding Class
intermediatesclassesdebug[package_name]databinding
Binding Layout
intermediatesdata-binding-layout-outdebuglayout
buildintermediates
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data class="MainActivityDataBinding">
<import type="com.awonwon.User"/>
<variable
name="user"
type="user"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.id}"/>
< …
</LinearLayout>
</layout>
Initialize variable
Set value
Layout
1. Initialize Variable
<data class="com.awonwon.MainActivityBinding">
<import type="com.awonwon.model.User" />
<import type="android.view.View" alias="v" />
<variable name="user" type="User" />
<variable name="datetime" type="String" />
<variable name="position" type="int" />
</data>
MainActivityBinding …
private com.awonwon.model.User mUser;
private String mDatetime;
private int mPotision;
private com.awonwon.model.User getUser();
private void setUser(com.awonwon.model.User user);
private String getDatetTime();
private void setDateTime(String datetime);
private int getPosition();
private void setPosition(int position);
2. Set Value Example
android:text="@{user.lastName}"
android:text="@{MyStringUtils.capitalize(user.firstName)}"
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"
android:padding="@{large? @dimen/largePadding :
(int)@dimen/smallPadding}"
Null Coalescing
android:text="@{user.displayName ?? user.lastName}"
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
• + - / * %
• +
• && || & | ^
• + - ! ~
• >> >>> <<
• == > < >= <=
• instanceof
• ()
• null
• Cast
•
• List Array Map
• ?:
※ XML encode : & = &amp;
<TextView android:text='@users.age > 18 ?
user.name.substring(0,1).toUpperCase() + "." +
user.lastName : @string/redacted'/>
BindAdapter
layout attribute
<ImageView
...
app:imageUrl="@{user.avatarUrl}
...
/>
BindAdapter
src field
@BindingAdapter(value = {"app:imageUrl"}, requireAll = true)
public static void loadImgUrl(ImageView view, String path){
Picasso.with(view.getContext())
.load(path)
.fit()
.centerCrop()
.into(view);
}
ID?
• static final MainActivityDataBinding
<TextView
android:id="@+id/view_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
public final TextView view_name;
JAVA Class
public class MainAcivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityDataBinding binding = DataBindingUtil.setContentView(
this, R.layout.main_layout);
User user = new User("8591", " ", "5", "2000");
binding.setUser(user);
}
}
DataBinding
public class MainAcivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityDataBinding binding = DataBindingUtil.setContentView(
this, R.layout.main_layout);
User user = new User("8591", " ", "5", "2000");
binding.setUser(user);
}
}
Create DataBinding Class
Set Variable Value
1. Create DataBinding Class
MainActivityDataBinding binding = DataBindingUtil.setContentView(
this, R.layout.main_layout);
ItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(c),
R.layout.item, parent, false);
2. Set Variable Value
binding.setUser(user);
binding.setVariable(BR.user, user);
…
Object Value
Observable Binding
1. BaseObservable & set method notifyPropertyChanged
public class User extends BaseObservable {
private String name;
@Bindable
public String getName() {
return name;
}
public void setLastName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
Observable Binding
2. ObservableField<T>
public final ObservableField<ItemAdapter> mItemAdapter = new ObservableField<>();
mItemAdapter.get().updateData(items);
mItemAdapter.set(adapter);
RecyclerAdapter
public class ItemViewHolder extends RecyclerView.ViewHolder {
private ItemBinding binding;
public ItemViewHolder(View itemView) {
super(itemView);
binding = DataBindingUtil.bind(itemView);
}
public ItemBinding getBinding(){
return binding;
}
public void setBinding(ItemBinding binding){
this.binding = binding;
}
}
RecyclerAdapter
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
GalleryItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(c),
R.layout.item_gallery, parent, false);
ItemViewHolder holder = new ItemViewHolder(binding.getRoot());
holder.setBinding(binding);
return holder;
}
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
holder.binding.setItem(mItems.get(position));
holder.binding.setPosition(position);
if (getItemViewType(position)==TYPE_SELECTED) {
holder.binding.setSelected(true);
}
holder.binding.executePendingBindings();
}
EditText
Two-Way Binding
Two-Way Binding
•Android Studio 2.1 Preview 3
<EditText android:text="@={user.name}" .../>
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0-alpha3'
}
https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/
DataBinding
Clean Code
Zero Reflection
Official Library
MMVM
Clean Code
Zero Reflection
Official Library
MMVM
Performance
• findViewById V.S. DataBinding
• findViewById
View
• DataBinding
Compiler Timer
View
RootView
LinearLayout
ImageView
RelativeLayout
TextView
LinearLayout
TextView
ImageView
Q&A
DataBinding Google I/O
https://realm.io/news/data-binding-android-boyar-mount/

Data binding 入門淺談