SlideShare a Scribd company logo
Speed Up Application Development
with Data Binding
Anokhin Mikle / Android Developer / MWDN Ltd.
First Part: Introduction
How to start (Java)
android {
buildToolsVersion "24.0.1"
dataBinding {
enabled = true
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
3
How to start (Kotlin)
apply plugin: 'kotlin-android'
android {
buildToolsVersion "24.0.1"
dataBinding {
enabled = true
}
}
dependencies {
kapt 'com.android.databinding:compiler:2.1.2'
}
kapt {
generateStubs = true
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.3'
}
}
4
Binding (Model)
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.anokmik.databinding.model.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
public class BindingModelFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.fragment_binding_model, container, false);
FragmentBindingModelBinding binding
= FragmentBindingModelBinding.bind(view);
binding.setUser(User.getDefault());
return view;
}
}
5
Data Binding doesn’t handle view state
so you should specify id for such views as usual
Binding (Ids)
public class BindingIdsFragment extends Fragment {
private TextView firstName;
private TextView lastName;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.fragment_binding_ids, container, false);
FragmentBindingIdsBinding binding
= FragmentBindingIdsBinding.bind(view);
firstName = binding.firstName;
lastName = binding.lastName;
return view;
}
@Override
public void onViewCreated(View view,
Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
User user = User.getDefault();
firstName.setText(user.firstName);
lastName.setText(user.lastName);
}
}
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/last_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
7
Generated Binding
8
public class FragmentBindingModelBinding
extends android.databinding.ViewDataBinding {
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
java.lang.String firstNameUser = null;
java.lang.String lastNameUser = null;
com.anokmik.databinding.model.User user = mUser;
if ((dirtyFlags & 0x3L) != 0) {
user = user;
if (user != null) {
firstNameUser = user.firstName;
lastNameUser = user.lastName;
}
}
if ((dirtyFlags & 0x3L) != 0) {
this.mboundView1.setText(firstNameUser);
this.mboundView2.setText(lastNameUser);
}
}
}
Bindings are generated at compile-time
Variables and Imports
<data>
<import type="android.graphics.drawable.Drawable" />
<import type="com.anokmik.databinding.model.User" />
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="user" type="User" />
<variable name="image" type="Drawable" />
<variable name="text" type="String" />
<variable name="array" type="String[]" />
<variable name="list" type="List&lt;String>"/>
<variable name="sparse" type="SparseArray&lt;String>"/>
<variable name="map" type="Map&lt;String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
<data>
<import type="android.app.Fragment"/>
<import type="android.support.v4.app.Fragment" alias="SupportFragment"/>
</data>
10
Simple Data Model
public class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
public class User {
public final String firstName;
public final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
11
Observable Data Model
public class NotifyGreeting extends BaseObservable {
private String name;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
}
public class ObservableGreeting {
public ObservableString name
= new ObservableString();
}
12
Include and Merge
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/name"
bind:user="@{user}" />
</LinearLayout>
</layout>
<layout
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<merge>
<include layout="@layout/name"
bind:user="@{user}"/>
</merge>
</layout>
13
Expressions
● mathematical +, -, /, *, %
● string concatenation +
● logical &&, ||
● binary &, |, ^
● unary +, -, !, ~
● shift >>, >>>, <<
● comparison ==, >, <, >=, <=
● instanceof
● grouping ()
● literals - character, String, numeric, null
● cast
● method calls
● field access
● array access []
● ternary operator ?:
android:enabled="@{communicator.isLoginValid &amp; communicator.isPasswordValid}"
14
Binding Providers
15
@BindingMethods({
@BindingMethod(type = TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"),
@BindingMethod(type = TextView.class, attribute = "android:inputType", method = "setRawInputType"),
@BindingMethod(type = TextView.class, attribute = "android:textAllCaps", method = "setAllCaps")
})
public class TextViewBindingAdapter {
@BindingAdapter("android:text")
public static void setText(TextView view, CharSequence text) {
...
}
}
public class Converters {
@BindingConversion
public static String convertObservableToString(ObservableString observableString) {
return observableString.get();
}
}
Data Binding Component
16
public class MainDataBindingComponent {
@BindingAdapter(value = {"defaultColor", "pressedColor"})
public void setButtonStateListBackground(Button button, int defaultColor, int pressedColor) {
button.setBackground(getButtonStateListDrawable(defaultColor, pressedColor));
}
}
public class DataBindingComponentProvider implements DataBindingComponent {
@Override
public MainDataBindingComponent getMainDataBindingComponent() {
return new MainDataBindingComponent();
}
}
DataBindingUtil.setDefaultComponent(new DataBindingComponentProvider());
DataBindingUtil.setContentView(this, R.layout.activity_main, new DataBindingComponentProvider());
DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false, new DataBindingComponentProvider());
Two-way Binding
17
android:text="@={communicator.editTextValue}"
AdapterView android:selectedItemPosition
CalendarView android:date
CompoundButton android:checked
DatePicker android:year / android:month / android:day
NumberPicker android:value
RadioGroup android:checkedButton
RatingBar android:rating
SeekBar android:progress
TabHost android:currentTab
TextView android:text
TimePicker android:hour / android:minute
app:color="@={communicator.color}"
Two-way binding requires getters and setters for fields
Second Part: Typical Use Cases
User Flow
20
Login Profile
User Layout Custom Items
21
Toolbar
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ToolbarTheme"
app:onNavigationClick="@{navigationClickListener}"
app:popupTheme="@style/PopupTheme" />
Support Toolbar Component
22
@BindingMethods({
@BindingMethod(type = Toolbar.class, attribute = "onMenuItemClick", method = "setOnMenuItemClickListener"),
@BindingMethod(type = Toolbar.class, attribute = "onNavigationClick", method = "setNavigationOnClickListener")
})
public final class SupportToolbarComponent {
}
@BindingMethods(
BindingMethod(type = Toolbar::class, attribute = "onMenuItemClick", method = "setOnMenuItemClickListener"),
BindingMethod(type = Toolbar::class, attribute = "onNavigationClick", method = "setNavigationOnClickListener")
)
class SupportToolbarComponent
User Layout Custom Items
23
Text Input Layout Button
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.login()}"
android:text="@string/login" />
<android.support.design.widget.TextInputLayout
style="@style/TextInputLayoutStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:editable="@{presenter.isEditing}"
app:error="@{@string/error_name_not_valid}"
app:showError="@{!presenter.firstNameValid}">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_first_name"
android:text="@={presenter.observableUser.firstName}" />
</android.support.design.widget.TextInputLayout>
Text Input Layout Component
24
public final class TextInputLayoutComponent {
@BindingAdapter({"error", "showError"})
public void setError(
TextInputLayout view, String error, boolean showError
) {
view.setError(showError ? error : null);
}
@BindingAdapter("editable")
public void setEditable(
TextInputLayout view, boolean isEditable
) {
view.setFocusable(isEditable);
EditText editText = view.getEditText();
if (editText != null) {
editText.setCursorVisible(isEditable);
editText.setFocusable(isEditable);
editText.setFocusableInTouchMode(isEditable);
Drawable background = editText.getBackground();
if (background != null) {
background.setAlpha(isEditable ? 255 : 0);
}
if (isEditable) {
Editable editableText = editText.getText();
int selectionStart = editText.getSelectionStart();
int selectionEnd = editText.getSelectionEnd();
if (!TextUtils.isEmpty(editableText)
&& (selectionStart == 0)
&& (selectionEnd == 0)) {
editText.setSelection(editableText.length());
}
}
}
}
}
class TextInputLayoutComponent {
@BindingAdapter("error", "showError")
fun setError(
view: TextInputLayout, error: String, showError: Boolean
) {
view.error = if (showError) error else null
}
@BindingAdapter("editable")
fun setEditable(
view: TextInputLayout, isEditable: Boolean
) {
view.isFocusable = isEditable
view.editText?.apply {
isCursorVisible = isEditable
isFocusable = isEditable
isFocusableInTouchMode = isEditable
background?.apply {
alpha = if (isEditable) 255 else 0
}
if (isEditable) {
val editableText = text
if (!TextUtils.isEmpty(editableText)
&& (selectionStart == 0)
&& (selectionEnd == 0)) {
setSelection(editableText.length)
}
}
}
}
}
Trips Flow
25
Trips List
Trip Event
Trip Details
Trips Layout Custom Items
26
Recycler View
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="@dimen/fragment_padding"
app:decoration="@{decoration}"
app:items="@{presenter.trips}"
app:layoutManager="@{layoutManager}"
app:viewHolderPresenter="@{presenter.viewHolderPresenter}" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{trip.title}"
android:textColor="@color/material_dark_primary_text_color"
android:textSize="@dimen/title_text_size"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{DateUtils.format(trip.startDate, trip.finishDate)}"
android:textColor="@color/material_dark_secondary_text_color"
android:textSize="@dimen/caption_text_size"
android:textStyle="bold" />
TextView (Title) TextView (Dates)
Recycler View Component
27
public final class RecyclerViewComponent {
@BindingAdapter({"items", "viewHolderPresenter"})
public void setContent(
final RecyclerView view,
List<?> list,
ViewHolderPresenter<?> viewHolderPresenter
) {
BinderRecyclerViewAdapter adapter = new BinderRecyclerViewAdapter(
LayoutInflater.from(view.getContext()),
list,
viewHolderPresenter
);
view.setAdapter(adapter);
if (list instanceof ObservableList) {
view.addOnAttachStateChangeListener(
new ObservableListAttachStateChangeListener(
(ObservableList) list,
new RecyclerViewListChangedCallback(adapter)
)
);
}
}
@BindingAdapter("decoration")
public void setDecoration(RecyclerView view,
RecyclerView.ItemDecoration decoration) {
view.addItemDecoration(decoration);
}
@BindingAdapter("decoration")
public void setDecoration(RecyclerView view,
RecyclerView.ItemDecoration[] decorations) {
for (RecyclerView.ItemDecoration decoration : decorations) {
view.addItemDecoration(decoration);
}
}
}
class RecyclerViewComponent {
@BindingAdapter("items", "viewHolderPresenter")
fun <T> setContent(
view: RecyclerView,
list: List<T>,
viewHolderPresenter: ViewHolderPresenter<T>
) {
val adapter = BinderRecyclerViewAdapter<T, ViewDataBinding>(
LayoutInflater.from(view.context),
list,
viewHolderPresenter
)
view.adapter = adapter
if (list is ObservableList<T>) {
view.addOnAttachStateChangeListener(
ObservableListAttachStateChangeListener(
list,
RecyclerViewListChangedCallback(adapter)
)
)
}
}
@BindingAdapter("decoration")
fun setDecoration(view: RecyclerView,
decoration: RecyclerView.ItemDecoration) {
view.addItemDecoration(decoration)
}
@BindingAdapter("decoration")
fun setDecoration(view: RecyclerView,
decorations: Array<RecyclerView.ItemDecoration>) {
for (decoration in decorations) {
view.addItemDecoration(decoration)
}
}
}
Trips Layout Custom Items
28
View Pager
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:items="@{presenter.photoAttachments}"
app:viewHolderPresenter="@{presenter.viewHolderPresenter}" />
View Pager Component
29
class ViewPagerComponent {
@BindingAdapter("items", "viewHolderPresenter")
fun <T> setContent(view: ViewPager, list: List<T>, viewHolderPresenter: ViewHolderPresenter<T>) {
val adapter = BinderViewPagerAdapter(
LayoutInflater.from(view.context), list, viewHolderPresenter
)
view.adapter = adapter
if (list is ObservableList<T>) {
view.addOnAttachStateChangeListener(
ObservableListAttachStateChangeListener(
list, ViewPagerListChangedCallback(adapter)
)
)
}
}
}
public final class ViewPagerComponent {
@BindingAdapter({"items", "viewHolderPresenter"})
public void setContent(ViewPager view, List<?> list, ViewHolderPresenter<?> viewHolderPresenter) {
BinderViewPagerAdapter adapter = new BinderViewPagerAdapter(
LayoutInflater.from(view.getContext()), list, viewHolderPresenter
);
view.setAdapter(adapter);
if (list instanceof ObservableList) {
view.addOnAttachStateChangeListener(new ObservableListAttachStateChangeListener(
(ObservableList) list, new ViewPagerListChangedCallback(adapter))
);
}
}
}
Image View Component
30
class ImageViewComponent {
@BindingAdapter("android:src")
fun loadImage(view: ImageView, imageUrl: String) {
Picasso.with(view.context).load(imageUrl).into(view)
}
}
public final class ImageViewComponent {
@BindingAdapter("android:src")
public void loadImage(ImageView view, String imageUrl) {
Picasso.with(view.getContext()).load(imageUrl).into(view);
}
}
Thanks for your attention!
sources:
first part: https://github.com/anokmik/data-binding
second part: https://github.com/anokmik/trip-assistant
mail: anokmik@gmail.com
skype: anokmik
References
● Data Binding Guide from Google (https://goo.gl/1yFPtt)
● No More findViewById (https://goo.gl/ugV86t)
● Android Data Binding: Adding Some Variability (https://goo.gl/aDTMmp)
● Android Data Binding: Express Yourself (https://goo.gl/NZ15Tz)
● Android Data Binding: Custom Setters (http://goo.gl/DnKgON)
● Android Data Binding: The Big Event (https://goo.gl/qcpdpU)
● Android Data Binding: That <include> Thing (https://goo.gl/QiqpQT)
● Android Data Binding: Let’s Flip This Thing (https://goo.gl/Gok1gv)
● Descent into Data Binding (https://goo.gl/1PTE7F)
● Two-way Data Binding (https://goo.gl/DQtRrh | https://goo.gl/KjY2Ze)
● Porting to Data Binding (https://goo.gl/7CA7vX)
● Advanced Data Binding (https://www.youtube.com/watch?v=DAmMN7m3wLU)
● Data Binding Techniques (https://www.youtube.com/watch?v=WdUbXWztKNY)
32
Q&A
Ad

More Related Content

What's hot (19)

Backbone.js
Backbone.jsBackbone.js
Backbone.js
Knoldus Inc.
 
Deep dive into Android Data Binding
Deep dive into Android Data BindingDeep dive into Android Data Binding
Deep dive into Android Data Binding
Radek Piekarz
 
Asp.NET MVC
Asp.NET MVCAsp.NET MVC
Asp.NET MVC
vrluckyin
 
Web components
Web componentsWeb components
Web components
Tudor Barbu
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databinding
Boulos Dib
 
ReRxSwift
ReRxSwiftReRxSwift
ReRxSwift
myposter GmbH
 
Retrofit Web Forms with MVC & T4
Retrofit Web Forms with MVC & T4Retrofit Web Forms with MVC & T4
Retrofit Web Forms with MVC & T4
soelinn
 
Hybrid apps - Your own mini Cordova
Hybrid apps - Your own mini CordovaHybrid apps - Your own mini Cordova
Hybrid apps - Your own mini Cordova
Ayman Mahfouz
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
simonetripodi
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 light
Michael Pustovit
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
Visual Engineering
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Fabio Collini
 
Reactивная тяга
Reactивная тягаReactивная тяга
Reactивная тяга
Vitebsk Miniq
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019
UA Mobile
 
React with Redux
React with ReduxReact with Redux
React with Redux
Stanimir Todorov
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Natasha Murashev
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
Fabio Collini
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
Yurii Kotov
 
MVVM with DataBinding on android
MVVM with DataBinding on androidMVVM with DataBinding on android
MVVM with DataBinding on android
Rodrigo Bressan
 
Deep dive into Android Data Binding
Deep dive into Android Data BindingDeep dive into Android Data Binding
Deep dive into Android Data Binding
Radek Piekarz
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databinding
Boulos Dib
 
Retrofit Web Forms with MVC & T4
Retrofit Web Forms with MVC & T4Retrofit Web Forms with MVC & T4
Retrofit Web Forms with MVC & T4
soelinn
 
Hybrid apps - Your own mini Cordova
Hybrid apps - Your own mini CordovaHybrid apps - Your own mini Cordova
Hybrid apps - Your own mini Cordova
Ayman Mahfouz
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
simonetripodi
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 light
Michael Pustovit
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
Visual Engineering
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Fabio Collini
 
Reactивная тяга
Reactивная тягаReactивная тяга
Reactивная тяга
Vitebsk Miniq
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019
UA Mobile
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Natasha Murashev
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
Fabio Collini
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
Yurii Kotov
 
MVVM with DataBinding on android
MVVM with DataBinding on androidMVVM with DataBinding on android
MVVM with DataBinding on android
Rodrigo Bressan
 

Viewers also liked (15)

Seminario nº-12
Seminario nº-12Seminario nº-12
Seminario nº-12
Daniela Vera Quijada
 
Σοφία Βέμπο ή «τραγουδίστρια της νίκης»
Σοφία Βέμπο ή «τραγουδίστρια  της νίκης»Σοφία Βέμπο ή «τραγουδίστρια  της νίκης»
Σοφία Βέμπο ή «τραγουδίστρια της νίκης»
70athinon
 
6java switch
6java switch6java switch
6java switch
trupti Deshmukh
 
Appletjava
AppletjavaAppletjava
Appletjava
trupti Deshmukh
 
4java
4java4java
4java
trupti Deshmukh
 
Outdoor Living In Nocatee
Outdoor Living In NocateeOutdoor Living In Nocatee
Outdoor Living In Nocatee
Nocatee
 
Javabeginners
JavabeginnersJavabeginners
Javabeginners
trupti Deshmukh
 
Javar expression
Javar expressionJavar expression
Javar expression
trupti Deshmukh
 
Estructuras de un Algoritmo
Estructuras de un AlgoritmoEstructuras de un Algoritmo
Estructuras de un Algoritmo
Yanina González
 
Datastructureinjava
DatastructureinjavaDatastructureinjava
Datastructureinjava
trupti Deshmukh
 
Personal investment report on february 7
Personal investment report on february 7Personal investment report on february 7
Personal investment report on february 7
Hoang (Henry) Le
 
Concurency
ConcurencyConcurency
Concurency
trupti Deshmukh
 
УЗИ в офтальмологии мелких домашних животных
УЗИ в офтальмологии мелких домашних животныхУЗИ в офтальмологии мелких домашних животных
УЗИ в офтальмологии мелких домашних животных
Соломаха Анна
 
Javafx
JavafxJavafx
Javafx
trupti Deshmukh
 
SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"
SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"
SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"
Inhacking
 
Σοφία Βέμπο ή «τραγουδίστρια της νίκης»
Σοφία Βέμπο ή «τραγουδίστρια  της νίκης»Σοφία Βέμπο ή «τραγουδίστρια  της νίκης»
Σοφία Βέμπο ή «τραγουδίστρια της νίκης»
70athinon
 
Outdoor Living In Nocatee
Outdoor Living In NocateeOutdoor Living In Nocatee
Outdoor Living In Nocatee
Nocatee
 
Estructuras de un Algoritmo
Estructuras de un AlgoritmoEstructuras de un Algoritmo
Estructuras de un Algoritmo
Yanina González
 
Personal investment report on february 7
Personal investment report on february 7Personal investment report on february 7
Personal investment report on february 7
Hoang (Henry) Le
 
УЗИ в офтальмологии мелких домашних животных
УЗИ в офтальмологии мелких домашних животныхУЗИ в офтальмологии мелких домашних животных
УЗИ в офтальмологии мелких домашних животных
Соломаха Анна
 
SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"
SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"
SE2016 IoT Maksym Antipov "Hardware development as a hobby and a job"
Inhacking
 
Ad

Similar to SE2016 Android Mikle Anokhin "Speed up application development with data binding" (20)

Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談
awonwon
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
OSCON Byrum
 
Android Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetAndroid Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection Widget
Prajyot Mainkar
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
Mario Jorge Pereira
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
InnovationM
 
Data Binding - Android by Harin Trivedi
Data Binding - Android by Harin TrivediData Binding - Android by Harin Trivedi
Data Binding - Android by Harin Trivedi
harintrivedi
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
Constantine Mars
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
DataArt
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
Eric Maxwell
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
Robert DeLuca
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
Anton Narusberg
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
Heather Rock
 
MVVM & Data Binding Library
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library
10Clouds
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011
Johan Nilsson
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
Spike Brehm
 
MVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) DetailsMVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) Details
Florina Muntenescu
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
Joonas Lehtinen
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
GeeksLab Odessa
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談
awonwon
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
OSCON Byrum
 
Android Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetAndroid Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection Widget
Prajyot Mainkar
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
Mario Jorge Pereira
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
InnovationM
 
Data Binding - Android by Harin Trivedi
Data Binding - Android by Harin TrivediData Binding - Android by Harin Trivedi
Data Binding - Android by Harin Trivedi
harintrivedi
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
Constantine Mars
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
DataArt
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
Eric Maxwell
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
Robert DeLuca
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
Anton Narusberg
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
Heather Rock
 
MVVM & Data Binding Library
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library
10Clouds
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011
Johan Nilsson
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
Spike Brehm
 
MVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) DetailsMVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) Details
Florina Muntenescu
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
GeeksLab Odessa
 
Ad

More from Inhacking (20)

SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"
SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"
SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"
Inhacking
 
SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...
SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...
SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...
Inhacking
 
SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...
SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...
SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...
Inhacking
 
SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...
SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...
SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...
Inhacking
 
SE2016 Company Development Vadym Gorenko "How to pass the death valley"
SE2016 Company Development Vadym Gorenko  "How to pass the death valley"SE2016 Company Development Vadym Gorenko  "How to pass the death valley"
SE2016 Company Development Vadym Gorenko "How to pass the death valley"
Inhacking
 
SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"
SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"
SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"
Inhacking
 
SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"
SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"
SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"
Inhacking
 
SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"
SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"
SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"
Inhacking
 
SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...
SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...
SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...
Inhacking
 
SE2016 Management Anna Lavrova "Gladiator in the suit crisis is our brand!"
SE2016 Management Anna Lavrova "Gladiator in the suit  crisis is our brand!"SE2016 Management Anna Lavrova "Gladiator in the suit  crisis is our brand!"
SE2016 Management Anna Lavrova "Gladiator in the suit crisis is our brand!"
Inhacking
 
SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...
SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...
SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...
Inhacking
 
SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...
SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...
SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...
Inhacking
 
SE2016 Management Yana Prolis "Please don't burn down!"
SE2016 Management Yana Prolis "Please don't burn down!"SE2016 Management Yana Prolis "Please don't burn down!"
SE2016 Management Yana Prolis "Please don't burn down!"
Inhacking
 
SE2016 Management Marina Bril "Management at marketing teams and performance"
SE2016 Management Marina Bril "Management at marketing teams and performance"SE2016 Management Marina Bril "Management at marketing teams and performance"
SE2016 Management Marina Bril "Management at marketing teams and performance"
Inhacking
 
SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"
SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"
SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"
Inhacking
 
SE2016 iOS Alexander Voronov "Test driven development in real world"
SE2016 iOS Alexander Voronov "Test driven development in real world"SE2016 iOS Alexander Voronov "Test driven development in real world"
SE2016 iOS Alexander Voronov "Test driven development in real world"
Inhacking
 
SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"
SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"
SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"
Inhacking
 
SE2016 JS Alexey Osipenko "Basics of functional reactive programming"
SE2016 JS Alexey Osipenko "Basics of functional reactive programming"SE2016 JS Alexey Osipenko "Basics of functional reactive programming"
SE2016 JS Alexey Osipenko "Basics of functional reactive programming"
Inhacking
 
SE2016 Java Vladimir Mikhel "Scrapping the web"
SE2016 Java Vladimir Mikhel "Scrapping the web"SE2016 Java Vladimir Mikhel "Scrapping the web"
SE2016 Java Vladimir Mikhel "Scrapping the web"
Inhacking
 
SE2016 Java Valerii Moisieienko "Apache HBase Workshop"
SE2016 Java Valerii Moisieienko "Apache HBase Workshop"SE2016 Java Valerii Moisieienko "Apache HBase Workshop"
SE2016 Java Valerii Moisieienko "Apache HBase Workshop"
Inhacking
 
SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"
SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"
SE2016 Fundraising Roman Kravchenko "Investment in Ukrainian IoT-Startups"
Inhacking
 
SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...
SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...
SE2016 Fundraising Wlodek Laskowski "Insider guide to successful fundraising ...
Inhacking
 
SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...
SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...
SE2016 Fundraising Andrey Sobol "Blockchain Crowdfunding or "Mommy, look, I l...
Inhacking
 
SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...
SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...
SE2016 Company Development Valentin Dombrovsky "Travel startups challenges an...
Inhacking
 
SE2016 Company Development Vadym Gorenko "How to pass the death valley"
SE2016 Company Development Vadym Gorenko  "How to pass the death valley"SE2016 Company Development Vadym Gorenko  "How to pass the death valley"
SE2016 Company Development Vadym Gorenko "How to pass the death valley"
Inhacking
 
SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"
SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"
SE2016 Marketing&PR Jan Keil "Do the right thing marketing for startups"
Inhacking
 
SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"
SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"
SE2016 PR&Marketing Mikhail Patalakha "ASO how to start and how to finish"
Inhacking
 
SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"
SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"
SE2016 UI/UX Alina Kononenko "Designing for Apple Watch and Apple TV"
Inhacking
 
SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...
SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...
SE2016 Management Mikhail Lebedinkiy "iAIST the first pure ukrainian corporat...
Inhacking
 
SE2016 Management Anna Lavrova "Gladiator in the suit crisis is our brand!"
SE2016 Management Anna Lavrova "Gladiator in the suit  crisis is our brand!"SE2016 Management Anna Lavrova "Gladiator in the suit  crisis is our brand!"
SE2016 Management Anna Lavrova "Gladiator in the suit crisis is our brand!"
Inhacking
 
SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...
SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...
SE2016 Management Aleksey Solntsev "Management of the projects in the conditi...
Inhacking
 
SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...
SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...
SE2016 Management Vitalii Laptenok "Processes and planning for a product comp...
Inhacking
 
SE2016 Management Yana Prolis "Please don't burn down!"
SE2016 Management Yana Prolis "Please don't burn down!"SE2016 Management Yana Prolis "Please don't burn down!"
SE2016 Management Yana Prolis "Please don't burn down!"
Inhacking
 
SE2016 Management Marina Bril "Management at marketing teams and performance"
SE2016 Management Marina Bril "Management at marketing teams and performance"SE2016 Management Marina Bril "Management at marketing teams and performance"
SE2016 Management Marina Bril "Management at marketing teams and performance"
Inhacking
 
SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"
SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"
SE2016 iOS Anton Fedorchenko "Swift for Server-side Development"
Inhacking
 
SE2016 iOS Alexander Voronov "Test driven development in real world"
SE2016 iOS Alexander Voronov "Test driven development in real world"SE2016 iOS Alexander Voronov "Test driven development in real world"
SE2016 iOS Alexander Voronov "Test driven development in real world"
Inhacking
 
SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"
SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"
SE2016 JS Gregory Shehet "Undefined on prod, or how to test a react application"
Inhacking
 
SE2016 JS Alexey Osipenko "Basics of functional reactive programming"
SE2016 JS Alexey Osipenko "Basics of functional reactive programming"SE2016 JS Alexey Osipenko "Basics of functional reactive programming"
SE2016 JS Alexey Osipenko "Basics of functional reactive programming"
Inhacking
 
SE2016 Java Vladimir Mikhel "Scrapping the web"
SE2016 Java Vladimir Mikhel "Scrapping the web"SE2016 Java Vladimir Mikhel "Scrapping the web"
SE2016 Java Vladimir Mikhel "Scrapping the web"
Inhacking
 
SE2016 Java Valerii Moisieienko "Apache HBase Workshop"
SE2016 Java Valerii Moisieienko "Apache HBase Workshop"SE2016 Java Valerii Moisieienko "Apache HBase Workshop"
SE2016 Java Valerii Moisieienko "Apache HBase Workshop"
Inhacking
 

SE2016 Android Mikle Anokhin "Speed up application development with data binding"

  • 1. Speed Up Application Development with Data Binding Anokhin Mikle / Android Developer / MWDN Ltd.
  • 3. How to start (Java) android { buildToolsVersion "24.0.1" dataBinding { enabled = true } } buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' } } 3
  • 4. How to start (Kotlin) apply plugin: 'kotlin-android' android { buildToolsVersion "24.0.1" dataBinding { enabled = true } } dependencies { kapt 'com.android.databinding:compiler:2.1.2' } kapt { generateStubs = true } buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.3' } } 4
  • 5. Binding (Model) <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.anokmik.databinding.model.User" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user.firstName}"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user.lastName}"/> </LinearLayout> </layout> public class BindingModelFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate( R.layout.fragment_binding_model, container, false); FragmentBindingModelBinding binding = FragmentBindingModelBinding.bind(view); binding.setUser(User.getDefault()); return view; } } 5
  • 6. Data Binding doesn’t handle view state so you should specify id for such views as usual
  • 7. Binding (Ids) public class BindingIdsFragment extends Fragment { private TextView firstName; private TextView lastName; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate( R.layout.fragment_binding_ids, container, false); FragmentBindingIdsBinding binding = FragmentBindingIdsBinding.bind(view); firstName = binding.firstName; lastName = binding.lastName; return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); User user = User.getDefault(); firstName.setText(user.firstName); lastName.setText(user.lastName); } } <layout xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/first_name" android:layout_width="match_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/last_name" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> </layout> 7
  • 8. Generated Binding 8 public class FragmentBindingModelBinding extends android.databinding.ViewDataBinding { @Override protected void executeBindings() { long dirtyFlags = 0; synchronized(this) { dirtyFlags = mDirtyFlags; mDirtyFlags = 0; } java.lang.String firstNameUser = null; java.lang.String lastNameUser = null; com.anokmik.databinding.model.User user = mUser; if ((dirtyFlags & 0x3L) != 0) { user = user; if (user != null) { firstNameUser = user.firstName; lastNameUser = user.lastName; } } if ((dirtyFlags & 0x3L) != 0) { this.mboundView1.setText(firstNameUser); this.mboundView2.setText(lastNameUser); } } }
  • 9. Bindings are generated at compile-time
  • 10. Variables and Imports <data> <import type="android.graphics.drawable.Drawable" /> <import type="com.anokmik.databinding.model.User" /> <import type="android.util.SparseArray"/> <import type="java.util.Map"/> <import type="java.util.List"/> <variable name="user" type="User" /> <variable name="image" type="Drawable" /> <variable name="text" type="String" /> <variable name="array" type="String[]" /> <variable name="list" type="List&lt;String>"/> <variable name="sparse" type="SparseArray&lt;String>"/> <variable name="map" type="Map&lt;String, String>"/> <variable name="index" type="int"/> <variable name="key" type="String"/> </data> <data> <import type="android.app.Fragment"/> <import type="android.support.v4.app.Fragment" alias="SupportFragment"/> </data> 10
  • 11. Simple Data Model public class User { private final String firstName; private final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } } public class User { public final String firstName; public final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } 11
  • 12. Observable Data Model public class NotifyGreeting extends BaseObservable { private String name; @Bindable public String getName() { return name; } public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); } } public class ObservableGreeting { public ObservableString name = new ObservableString(); } 12
  • 13. Include and Merge <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto"> <data> <variable name="user" type="com.example.User" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/name" bind:user="@{user}" /> </LinearLayout> </layout> <layout xmlns:bind="http://schemas.android.com/apk/res-auto"> <data> <variable name="user" type="com.example.User"/> </data> <merge> <include layout="@layout/name" bind:user="@{user}"/> </merge> </layout> 13
  • 14. Expressions ● mathematical +, -, /, *, % ● string concatenation + ● logical &&, || ● binary &, |, ^ ● unary +, -, !, ~ ● shift >>, >>>, << ● comparison ==, >, <, >=, <= ● instanceof ● grouping () ● literals - character, String, numeric, null ● cast ● method calls ● field access ● array access [] ● ternary operator ?: android:enabled="@{communicator.isLoginValid &amp; communicator.isPasswordValid}" 14
  • 15. Binding Providers 15 @BindingMethods({ @BindingMethod(type = TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"), @BindingMethod(type = TextView.class, attribute = "android:inputType", method = "setRawInputType"), @BindingMethod(type = TextView.class, attribute = "android:textAllCaps", method = "setAllCaps") }) public class TextViewBindingAdapter { @BindingAdapter("android:text") public static void setText(TextView view, CharSequence text) { ... } } public class Converters { @BindingConversion public static String convertObservableToString(ObservableString observableString) { return observableString.get(); } }
  • 16. Data Binding Component 16 public class MainDataBindingComponent { @BindingAdapter(value = {"defaultColor", "pressedColor"}) public void setButtonStateListBackground(Button button, int defaultColor, int pressedColor) { button.setBackground(getButtonStateListDrawable(defaultColor, pressedColor)); } } public class DataBindingComponentProvider implements DataBindingComponent { @Override public MainDataBindingComponent getMainDataBindingComponent() { return new MainDataBindingComponent(); } } DataBindingUtil.setDefaultComponent(new DataBindingComponentProvider()); DataBindingUtil.setContentView(this, R.layout.activity_main, new DataBindingComponentProvider()); DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false, new DataBindingComponentProvider());
  • 17. Two-way Binding 17 android:text="@={communicator.editTextValue}" AdapterView android:selectedItemPosition CalendarView android:date CompoundButton android:checked DatePicker android:year / android:month / android:day NumberPicker android:value RadioGroup android:checkedButton RatingBar android:rating SeekBar android:progress TabHost android:currentTab TextView android:text TimePicker android:hour / android:minute app:color="@={communicator.color}"
  • 18. Two-way binding requires getters and setters for fields
  • 19. Second Part: Typical Use Cases
  • 21. User Layout Custom Items 21 Toolbar <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ToolbarTheme" app:onNavigationClick="@{navigationClickListener}" app:popupTheme="@style/PopupTheme" />
  • 22. Support Toolbar Component 22 @BindingMethods({ @BindingMethod(type = Toolbar.class, attribute = "onMenuItemClick", method = "setOnMenuItemClickListener"), @BindingMethod(type = Toolbar.class, attribute = "onNavigationClick", method = "setNavigationOnClickListener") }) public final class SupportToolbarComponent { } @BindingMethods( BindingMethod(type = Toolbar::class, attribute = "onMenuItemClick", method = "setOnMenuItemClickListener"), BindingMethod(type = Toolbar::class, attribute = "onNavigationClick", method = "setNavigationOnClickListener") ) class SupportToolbarComponent
  • 23. User Layout Custom Items 23 Text Input Layout Button <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{() -> presenter.login()}" android:text="@string/login" /> <android.support.design.widget.TextInputLayout style="@style/TextInputLayoutStyle" android:layout_width="match_parent" android:layout_height="wrap_content" app:editable="@{presenter.isEditing}" app:error="@{@string/error_name_not_valid}" app:showError="@{!presenter.firstNameValid}"> <android.support.design.widget.TextInputEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_first_name" android:text="@={presenter.observableUser.firstName}" /> </android.support.design.widget.TextInputLayout>
  • 24. Text Input Layout Component 24 public final class TextInputLayoutComponent { @BindingAdapter({"error", "showError"}) public void setError( TextInputLayout view, String error, boolean showError ) { view.setError(showError ? error : null); } @BindingAdapter("editable") public void setEditable( TextInputLayout view, boolean isEditable ) { view.setFocusable(isEditable); EditText editText = view.getEditText(); if (editText != null) { editText.setCursorVisible(isEditable); editText.setFocusable(isEditable); editText.setFocusableInTouchMode(isEditable); Drawable background = editText.getBackground(); if (background != null) { background.setAlpha(isEditable ? 255 : 0); } if (isEditable) { Editable editableText = editText.getText(); int selectionStart = editText.getSelectionStart(); int selectionEnd = editText.getSelectionEnd(); if (!TextUtils.isEmpty(editableText) && (selectionStart == 0) && (selectionEnd == 0)) { editText.setSelection(editableText.length()); } } } } } class TextInputLayoutComponent { @BindingAdapter("error", "showError") fun setError( view: TextInputLayout, error: String, showError: Boolean ) { view.error = if (showError) error else null } @BindingAdapter("editable") fun setEditable( view: TextInputLayout, isEditable: Boolean ) { view.isFocusable = isEditable view.editText?.apply { isCursorVisible = isEditable isFocusable = isEditable isFocusableInTouchMode = isEditable background?.apply { alpha = if (isEditable) 255 else 0 } if (isEditable) { val editableText = text if (!TextUtils.isEmpty(editableText) && (selectionStart == 0) && (selectionEnd == 0)) { setSelection(editableText.length) } } } } }
  • 25. Trips Flow 25 Trips List Trip Event Trip Details
  • 26. Trips Layout Custom Items 26 Recycler View <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:padding="@dimen/fragment_padding" app:decoration="@{decoration}" app:items="@{presenter.trips}" app:layoutManager="@{layoutManager}" app:viewHolderPresenter="@{presenter.viewHolderPresenter}" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@{trip.title}" android:textColor="@color/material_dark_primary_text_color" android:textSize="@dimen/title_text_size" android:textStyle="bold" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{DateUtils.format(trip.startDate, trip.finishDate)}" android:textColor="@color/material_dark_secondary_text_color" android:textSize="@dimen/caption_text_size" android:textStyle="bold" /> TextView (Title) TextView (Dates)
  • 27. Recycler View Component 27 public final class RecyclerViewComponent { @BindingAdapter({"items", "viewHolderPresenter"}) public void setContent( final RecyclerView view, List<?> list, ViewHolderPresenter<?> viewHolderPresenter ) { BinderRecyclerViewAdapter adapter = new BinderRecyclerViewAdapter( LayoutInflater.from(view.getContext()), list, viewHolderPresenter ); view.setAdapter(adapter); if (list instanceof ObservableList) { view.addOnAttachStateChangeListener( new ObservableListAttachStateChangeListener( (ObservableList) list, new RecyclerViewListChangedCallback(adapter) ) ); } } @BindingAdapter("decoration") public void setDecoration(RecyclerView view, RecyclerView.ItemDecoration decoration) { view.addItemDecoration(decoration); } @BindingAdapter("decoration") public void setDecoration(RecyclerView view, RecyclerView.ItemDecoration[] decorations) { for (RecyclerView.ItemDecoration decoration : decorations) { view.addItemDecoration(decoration); } } } class RecyclerViewComponent { @BindingAdapter("items", "viewHolderPresenter") fun <T> setContent( view: RecyclerView, list: List<T>, viewHolderPresenter: ViewHolderPresenter<T> ) { val adapter = BinderRecyclerViewAdapter<T, ViewDataBinding>( LayoutInflater.from(view.context), list, viewHolderPresenter ) view.adapter = adapter if (list is ObservableList<T>) { view.addOnAttachStateChangeListener( ObservableListAttachStateChangeListener( list, RecyclerViewListChangedCallback(adapter) ) ) } } @BindingAdapter("decoration") fun setDecoration(view: RecyclerView, decoration: RecyclerView.ItemDecoration) { view.addItemDecoration(decoration) } @BindingAdapter("decoration") fun setDecoration(view: RecyclerView, decorations: Array<RecyclerView.ItemDecoration>) { for (decoration in decorations) { view.addItemDecoration(decoration) } } }
  • 28. Trips Layout Custom Items 28 View Pager <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:items="@{presenter.photoAttachments}" app:viewHolderPresenter="@{presenter.viewHolderPresenter}" />
  • 29. View Pager Component 29 class ViewPagerComponent { @BindingAdapter("items", "viewHolderPresenter") fun <T> setContent(view: ViewPager, list: List<T>, viewHolderPresenter: ViewHolderPresenter<T>) { val adapter = BinderViewPagerAdapter( LayoutInflater.from(view.context), list, viewHolderPresenter ) view.adapter = adapter if (list is ObservableList<T>) { view.addOnAttachStateChangeListener( ObservableListAttachStateChangeListener( list, ViewPagerListChangedCallback(adapter) ) ) } } } public final class ViewPagerComponent { @BindingAdapter({"items", "viewHolderPresenter"}) public void setContent(ViewPager view, List<?> list, ViewHolderPresenter<?> viewHolderPresenter) { BinderViewPagerAdapter adapter = new BinderViewPagerAdapter( LayoutInflater.from(view.getContext()), list, viewHolderPresenter ); view.setAdapter(adapter); if (list instanceof ObservableList) { view.addOnAttachStateChangeListener(new ObservableListAttachStateChangeListener( (ObservableList) list, new ViewPagerListChangedCallback(adapter)) ); } } }
  • 30. Image View Component 30 class ImageViewComponent { @BindingAdapter("android:src") fun loadImage(view: ImageView, imageUrl: String) { Picasso.with(view.context).load(imageUrl).into(view) } } public final class ImageViewComponent { @BindingAdapter("android:src") public void loadImage(ImageView view, String imageUrl) { Picasso.with(view.getContext()).load(imageUrl).into(view); } }
  • 31. Thanks for your attention! sources: first part: https://github.com/anokmik/data-binding second part: https://github.com/anokmik/trip-assistant mail: [email protected] skype: anokmik
  • 32. References ● Data Binding Guide from Google (https://goo.gl/1yFPtt) ● No More findViewById (https://goo.gl/ugV86t) ● Android Data Binding: Adding Some Variability (https://goo.gl/aDTMmp) ● Android Data Binding: Express Yourself (https://goo.gl/NZ15Tz) ● Android Data Binding: Custom Setters (http://goo.gl/DnKgON) ● Android Data Binding: The Big Event (https://goo.gl/qcpdpU) ● Android Data Binding: That <include> Thing (https://goo.gl/QiqpQT) ● Android Data Binding: Let’s Flip This Thing (https://goo.gl/Gok1gv) ● Descent into Data Binding (https://goo.gl/1PTE7F) ● Two-way Data Binding (https://goo.gl/DQtRrh | https://goo.gl/KjY2Ze) ● Porting to Data Binding (https://goo.gl/7CA7vX) ● Advanced Data Binding (https://www.youtube.com/watch?v=DAmMN7m3wLU) ● Data Binding Techniques (https://www.youtube.com/watch?v=WdUbXWztKNY) 32
  • 33. Q&A