Denis Kniazhev
Java EE - 8 years
Android - 2 years
Did some Java desktop, Javascript, PHP, Databases, iOS along the way
Currently Development Manager of Mobile project (iOS and Android)
View
Model
Template
Compiles
Template
Model
View
Model is the single source of truth
Compiles
<LinearLayout …>
<TextView android:id="@+id/name"/>
<TextView android:id="@+id/lastName"/>
</LinearLayout>private TextView name
private TextView lastName;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
name = (TextView) findViewById(R.id.name);
lastName = (TextView) findViewById(R.id.lastName);
}
public void updateUI(User user) {
if (user == null) {
name.setText(null);
lastName.setText(null);
} else {
name.setText(user.getName());
lastName.setText(user.getLastName());
}findViewById
null check
name and lastName need to be set separately
@Bind(R.id.name) TextView name
@Bind(R.id.lastName) TextView lastName;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
public void updateUI(User user) {
if (user == null) {
name.setText(null);
lastName.setText(null);
} else {
name.setText(user.getName());
lastName.setText(user.getLastName());
}
}<layout>
<data>
<variable name="user"
type="com.android.example.User"/>
</data>
<LinearLayout …>
<TextView android:text="@{user.name}"/>
<TextView android:text="@{user.lastName}"/>
</LinearLayout>
</layout>private ActivityMainBinding binding;
protected void onCreate(Bundle savedInstanceState) {
binding = DataBindingUtil.setContentView(
this, R.layout.activity_main);
}
public void updateUI(User user) {
binding.setUser(user);
}activity_main.xml:
Expression language
Generated class
Call this instead of activity.setContentView
Declare variable
mostly Java
Missing operators: this, super, new
Resources:
<TextView android:text='@{user.isMale ? @string/male : @string/female}' />
<data>
<import type="android.view.View"/>
</data>
...
<TextView android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}" .../>
Imports:
Variables:
<data>
<import type="com.example.User"/>
<import type="java.util.List"/>
<variable name="user" type="User"/>
<variable name="userList" type="List<User>"/>
</data>
No NullPointerException
{
"user": {
"name": "John"
}
}if(response != null && response.user != null) {
nameView.setText(response.user.name);
}android:text="@{response.user.name}"Null coalescing
textView.setText(user.name != null
? user.name : "unknown");android:text='@{user.name ?? "unknown"}'becomes
becomes
public class User extends BaseObservable {
private String firstName;
@Bindable
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
}<TextView android:text="@{user.firstName}" />extend BaseObservable or implement Observable
Annotate fields with @Bindable
Notify of field change
public class User {
public final ObservableField<String> firstName =
new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
user.firstName.set("John");
int age = user.age.get();<TextView android:text="@{user.firstName}" />
<TextView android:text="@{user.age}" />ObservableFields are implemented for all primitives and for Objects
call get and set
reference the fields in XML
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
classpath 'com.android.databinding:dataBinder:1.0-rc4'
}
}<LinearLayout …>
<TextView .../>
<TextView .../>
</LinearLayout>activity_main.xml:
<layout>
<data>
...
</data>
<LinearLayout …>
<TextView .../>
<TextView .../>
</LinearLayout>
</layout>MainActivity.java:
ActivityMainBinding binding =
DataBindingUtil.setContentView(
this, R.layout.activity_main);setContentViev(R.layout.activity_main);becomes
becomes
All code generation and expression parsing happens at compile time => if an expression has error the project won't compile
No reflection, no runtime overhead
The compiler needs to traverse the views once - no findViewById needed
textView = (TextView) findViewById(R.id.myTextView);textView = binding.myTextView;Expressions are cached
<TextView android:text='@{"Hello " + user.isMale ? @string/male : @string/female}' />
<TextView android:text='@{"Goodbye " + user.isMale ? @string/male : @string/female}' />UI updates are batched together.
Bindings can be updated on ANY thread.
becomes
Yigit Boyar and George Mount: Databinding talk
Official Databinding guide:
Android Developer Backstage podcast: Databinding
http://androidbackstage.blogspot.com/2015/09/episode-35-data-bound.html
Droidcon NYC 2015 - Data Binding Techniques
Questions?