SlideShare a Scribd company logo
Data Binding 2.0
Анохин Михаил / Android Developer / MWDN Ltd.
Data Binding
● представлен на Google I/O 2015
● официальная библиотека от Google
● генерирует биндинг во время компиляции
● позволяет реализовать двусторонний биндинг
● доступна стабильная версия 2.1
2
public class FindViewByIdFragment 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_simple_as_is, container, false);
firstName = (TextView) view.findViewById(R.id.first_name);
lastName = (TextView) view.findViewById(R.id.last_name);
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);
}
}
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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>
findViewById
3
public class ButterKnifeFragment extends Fragment {
@Bind(R.id.first_name)
TextView firstName;
@Bind(R.id.last_name)
TextView lastName;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.fragment_simple_as_is, container, false);
ButterKnife.bind(this, view);
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);
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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>
ButterKnife
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
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>
6
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;
}
}
7
Configuration
android {
...
buildToolsVersion "23.0.2"
...
dataBinding {
enabled = true
}
...
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
}
}
8
Compile-time Generation
View view = inflater.inflate(R.layout.fragment_main, container, false);
FragmentMainBinding binding = FragmentMainBinding.bind(view);
<data class="FragmentMainBinding">
...
</data>
<data class=".FragmentMainBinding">
...
</data>
<data class="com.example.FragmentMainBinding">
...
</data>
9
Generated classes location: /build/intermediates/classes/{$buildType}/{$applicationId}/databinding
Variables and Imports
public abstract User getUser();
public abstract void setUser(User user);
public abstract Drawable getImage();
public abstract void setImage(Drawable image);
public abstract String getText();
public abstract void setText(String text);
<data>
<import type="android.graphics.drawable.Drawable" />
<import type="com.anokmik.databinding.model.User" />
<variable name="user" type="User" />
<variable name="image" type="Drawable" />
<variable name="text" type="String" />
</data>
10
Variables and Imports
<data>
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<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>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{titles[0]}" />
<data>
<import type="android.app.Fragment"/>
<import type="android.support.v4.app.Fragment" alias="SupportFragment"/>
</data>
11
Data Objects
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
Data Objects (Example)
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>
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}"
15
Expressions (Example)
16
Null
android:text="@{user.firstName ?? user.lastName}"
android:text="@{user.firstName != null ? user.firstName : user.lastName}"
android:visibility="@{communicator.greeting.name.length > 0 ? View.VISIBLE : View.GONE}"
17
Setters and Binding Adapters
bind:layoutManager="@{communicator.layoutManager}"
18
android:text="@{user.firstName}"
@BindingAdapter("android:text")
public static void setText(TextView view, CharSequence text) {
...
}
android:onTextChanged="@{communicator.onLoginTextChanged}"
@BindingAdapter(value = {"android:beforeTextChanged", "android:onTextChanged",
"android:afterTextChanged", "android:textAttrChanged"}, requireAll = false)
public static void setTextWatcher(TextView view, final BeforeTextChanged before, final OnTextChanged on,
final AfterTextChanged after, final InverseBindingListener textAttrChanged) {
...
}
bind:adapter="@{communicator.adapter}"
Data Binding Component
19
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());
Binding Methods
20
@BindingMethods({
@BindingMethod(type = View.class, attribute = "android:onDrag", method = "setOnDragListener"),
@BindingMethod(type = View.class, attribute = "android:onClick", method = "setOnClickListener"),
@BindingMethod(type = View.class, attribute = "android:onTouch", method = "setOnTouchListener"),
})
public class ViewBindingAdapter {
...
}
@BindingMethods({
@BindingMethod(type = TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"),
@BindingMethod(type = TextView.class, attribute = "android:inputType", method = "setRawInputType")
})
public class TextViewBindingAdapter {
...
}
Binding Converters
public class Converters {
@BindingConversion
public static String convertObservableToString(ObservableString observableString) {
return observableString.get();
}
}
21
Two Way Binding
22
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
23
@InverseBindingMethods({
@InverseBindingMethod(type = MaterialDesignPrimaryPaletteView.class, attribute = "color")
})
public class MaterialDesignPrimaryPaletteView extends GridLayout implements View.OnClickListener {
private OnColorChangeListener listener;
private int color;
...
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public void setOnColorChangeListener(OnColorChangeListener listener) {
this.listener = listener;
}
public interface OnColorChangeListener {
void onColorChange(MaterialDesignPrimaryPaletteView view, int color);
}
}
Two Way Binding
24
public class TwoWayDataBindingComponent {
@BindingAdapter(value = {"onColorChange", "colorAttrChanged"}, requireAll = false)
public void setColorListener(MaterialDesignPrimaryPaletteView view,
final OnColorChangeListener listener, final InverseBindingListener colorChange) {
if (colorChange == null) {
view.setOnColorChangeListener(listener);
} else {
view.setOnColorChangeListener(new OnColorChangeListener() {
@Override
public void onColorChange(MaterialDesignPrimaryPaletteView view, int color) {
if (listener != null) {
listener.onColorChange(view, color);
}
colorChange.onChange();
}
});
}
}
@BindingAdapter("color")
public void setColor(MaterialDesignPrimaryPaletteView view, int color) {
if (color != view.getColor()) {
view.setColor(color);
}
}
}
Lambda Expressions
25
android:onClick="@{() -> communicator.showToast()}"
android:onClick="@{() -> communicator.switchState()}"
android:onClick="@{(v) -> communicator.replaceFragment(v.id)}"
Binding Executor
26
private static final boolean USE_CHOREOGRAPHER = SDK_INT >= 16;
...
protected ViewDataBinding(DataBindingComponent bindingComponent,
View root, int localFieldCount) {
...
if (USE_CHOREOGRAPHER) {
mChoreographer = Choreographer.getInstance();
mFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
mRebindRunnable.run();
}
};
} else {
mFrameCallback = null;
mUIThreadHandler = new Handler(Looper.myLooper());
}
}
Binding Execution
27
protected void requestRebind() {
...
if (USE_CHOREOGRAPHER) {
mChoreographer.postFrameCallback(mFrameCallback);
} else {
mUIThreadHandler.post(mRebindRunnable);
}
}
private final Runnable mRebindRunnable = new Runnable() {
@Override
public void run() {
...
executePendingBindings();
}
};
public void executePendingBindings() {
...
if (!mRebindHalted) {
executeBindings();
...
}
...
}
Generated Binding
28
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);
}
}
...
}
References
● http://developer.android.com/tools/data-binding/guide.html
● https://realm.io/news/data-binding-android-boyar-mount/
● https://speakerdeck.com/rciovati/binding-data-with-android-databinding
● https://medium.com/@fabioCollini/android-data-binding-f9f9d3afc761
● https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/
● https://www.youtube.com/watch?v=ssayKH0tudk
● https://www.youtube.com/watch?v=WdUbXWztKNY
● https://www.youtube.com/watch?v=DAmMN7m3wLU
29
Thanks for your attention!
source: https://github.com/anokmik/data-binding
mail: anokmik@gmail.com
skype: anokmik
AMA
(Ask Me Anything)
Ad

More Related Content

What's hot (19)

Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
Eric Maxwell
 
Dmytro Zaitsev Viper: make your mvp cleaner
Dmytro Zaitsev Viper: make your mvp cleanerDmytro Zaitsev Viper: make your mvp cleaner
Dmytro Zaitsev Viper: make your mvp cleaner
Аліна Шепшелей
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
Joonas Lehtinen
 
Jquery
JqueryJquery
Jquery
adm_exoplatform
 
Jackson 사용법
Jackson 사용법Jackson 사용법
Jackson 사용법
남윤 김
 
Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto
melbournepatterns
 
Build your own entity with Drupal
Build your own entity with DrupalBuild your own entity with Drupal
Build your own entity with Drupal
Marco Vito Moscaritolo
 
Vaadin JPAContainer
Vaadin JPAContainerVaadin JPAContainer
Vaadin JPAContainer
cmkandemir
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
Sergey Bolshchikov
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in Drupal
Fredric Mitchell
 
The Principle of Hybrid App.
The Principle of Hybrid App.The Principle of Hybrid App.
The Principle of Hybrid App.
musart Park
 
ハンズオン資料 電話を作ろう(v2.x用)
ハンズオン資料 電話を作ろう(v2.x用)ハンズオン資料 電話を作ろう(v2.x用)
ハンズオン資料 電話を作ろう(v2.x用)
Kenji Sakashita
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
NAVER Engineering
 
Terrific Frontends
Terrific FrontendsTerrific Frontends
Terrific Frontends
Remo Brunschwiler
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Denis Voituron
 
Android Testing
Android TestingAndroid Testing
Android Testing
Evan Lin
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
Allan Huang
 
French kit2019
French kit2019French kit2019
French kit2019
Nataliya Patsovska
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
Marco Vito Moscaritolo
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
Eric Maxwell
 
Jackson 사용법
Jackson 사용법Jackson 사용법
Jackson 사용법
남윤 김
 
Vaadin JPAContainer
Vaadin JPAContainerVaadin JPAContainer
Vaadin JPAContainer
cmkandemir
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in Drupal
Fredric Mitchell
 
The Principle of Hybrid App.
The Principle of Hybrid App.The Principle of Hybrid App.
The Principle of Hybrid App.
musart Park
 
ハンズオン資料 電話を作ろう(v2.x用)
ハンズオン資料 電話を作ろう(v2.x用)ハンズオン資料 電話を作ろう(v2.x用)
ハンズオン資料 電話を作ろう(v2.x用)
Kenji Sakashita
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
NAVER Engineering
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Denis Voituron
 
Android Testing
Android TestingAndroid Testing
Android Testing
Evan Lin
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
Allan Huang
 

Viewers also liked (20)

"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин
Fwdays
 
Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...
Fwdays
 
Светлана Старикова "Building a self-managing team: why you should not have e...
 Светлана Старикова "Building a self-managing team: why you should not have e... Светлана Старикова "Building a self-managing team: why you should not have e...
Светлана Старикова "Building a self-managing team: why you should not have e...
Fwdays
 
4 puchnina.pptx
4 puchnina.pptx4 puchnina.pptx
4 puchnina.pptx
Fwdays
 
Сергей Жук "Android Performance Tips & Tricks"
Сергей Жук "Android Performance Tips & Tricks"Сергей Жук "Android Performance Tips & Tricks"
Сергей Жук "Android Performance Tips & Tricks"
Fwdays
 
"Frameworks in 2015" Андрей Листочкин
"Frameworks in 2015" Андрей Листочкин"Frameworks in 2015" Андрей Листочкин
"Frameworks in 2015" Андрей Листочкин
Fwdays
 
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностьюТрансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Fwdays
 
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Fwdays
 
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Fwdays
 
Алексей Волков "Интерактивные декларативные графики на React+D3"
Алексей Волков "Интерактивные декларативные графики на React+D3"Алексей Волков "Интерактивные декларативные графики на React+D3"
Алексей Волков "Интерактивные декларативные графики на React+D3"
Fwdays
 
Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"
Fwdays
 
Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"
Fwdays
 
"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук
Fwdays
 
Александр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with SwiftАлександр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with Swift
Fwdays
 
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа СахароваШвейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Fwdays
 
"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец
Fwdays
 
Designing for Privacy
Designing for PrivacyDesigning for Privacy
Designing for Privacy
exultantwarning51
 
Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"
Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"
Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"
Fwdays
 
Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)
Fwdays
 
Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"
Fwdays
 
"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин
Fwdays
 
Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...
Fwdays
 
Светлана Старикова "Building a self-managing team: why you should not have e...
 Светлана Старикова "Building a self-managing team: why you should not have e... Светлана Старикова "Building a self-managing team: why you should not have e...
Светлана Старикова "Building a self-managing team: why you should not have e...
Fwdays
 
4 puchnina.pptx
4 puchnina.pptx4 puchnina.pptx
4 puchnina.pptx
Fwdays
 
Сергей Жук "Android Performance Tips & Tricks"
Сергей Жук "Android Performance Tips & Tricks"Сергей Жук "Android Performance Tips & Tricks"
Сергей Жук "Android Performance Tips & Tricks"
Fwdays
 
"Frameworks in 2015" Андрей Листочкин
"Frameworks in 2015" Андрей Листочкин"Frameworks in 2015" Андрей Листочкин
"Frameworks in 2015" Андрей Листочкин
Fwdays
 
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностьюТрансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Fwdays
 
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Fwdays
 
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Fwdays
 
Алексей Волков "Интерактивные декларативные графики на React+D3"
Алексей Волков "Интерактивные декларативные графики на React+D3"Алексей Волков "Интерактивные декларативные графики на React+D3"
Алексей Волков "Интерактивные декларативные графики на React+D3"
Fwdays
 
Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"
Fwdays
 
Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"
Fwdays
 
"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук
Fwdays
 
Александр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with SwiftАлександр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with Swift
Fwdays
 
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа СахароваШвейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Fwdays
 
"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец
Fwdays
 
Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"
Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"
Анастасия Войтова: "Building profanity filters on mobile: clbuttic sh!t"
Fwdays
 
Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)
Fwdays
 
Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"
Fwdays
 
Ad

Similar to Михаил Анохин "Data binding 2.0" (20)

Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
C.T.Co
 
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
 
Androidppt 1
Androidppt 1Androidppt 1
Androidppt 1
edwardyangey
 
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
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
Ignacio Coloma
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
Yekmer Simsek
 
Data Binding
Data BindingData Binding
Data Binding
LAY Leangsros
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
Murat Yener
 
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
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
Alexander Varwijk
 
Fragments anyone
Fragments anyone Fragments anyone
Fragments anyone
Yossi Elkrief
 
Data Binding - Android by Harin Trivedi
Data Binding - Android by Harin TrivediData Binding - Android by Harin Trivedi
Data Binding - Android by Harin Trivedi
harintrivedi
 
Android workshop
Android workshopAndroid workshop
Android workshop
Michael Galpin
 
Cours Authentification FireBase Sign/Sign Up
Cours Authentification FireBase Sign/Sign UpCours Authentification FireBase Sign/Sign Up
Cours Authentification FireBase Sign/Sign Up
amar719595
 
Data binding w Androidzie
Data binding w AndroidzieData binding w Androidzie
Data binding w Androidzie
The Software House
 
Android development
Android developmentAndroid development
Android development
Gregoire BARRET
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
Chris Weldon
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
jojule
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
C.T.Co
 
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
 
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
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
Yekmer Simsek
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
Murat Yener
 
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
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
Alexander Varwijk
 
Data Binding - Android by Harin Trivedi
Data Binding - Android by Harin TrivediData Binding - Android by Harin Trivedi
Data Binding - Android by Harin Trivedi
harintrivedi
 
Cours Authentification FireBase Sign/Sign Up
Cours Authentification FireBase Sign/Sign UpCours Authentification FireBase Sign/Sign Up
Cours Authentification FireBase Sign/Sign Up
amar719595
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
jojule
 
Ad

More from Fwdays (20)

Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Fwdays
 
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her..."Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
Fwdays
 
"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko
Fwdays
 
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
Fwdays
 
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5..."Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
Fwdays
 
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
Fwdays
 
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V..."Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
Fwdays
 
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka..."Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
Fwdays
 
Performance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продуктуPerformance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продукту
Fwdays
 
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu..."Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
Fwdays
 
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea..."AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
Fwdays
 
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio..."Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
Fwdays
 
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil..."Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
Fwdays
 
"39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment..."39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment...
Fwdays
 
"From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte..."From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte...
Fwdays
 
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
Fwdays
 
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
Fwdays
 
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
Fwdays
 
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake..."Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
Fwdays
 
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest..."Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
Fwdays
 
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Fwdays
 
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her..."Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
Fwdays
 
"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko
Fwdays
 
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
Fwdays
 
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5..."Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
Fwdays
 
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
Fwdays
 
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V..."Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
Fwdays
 
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka..."Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
Fwdays
 
Performance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продуктуPerformance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продукту
Fwdays
 
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu..."Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
Fwdays
 
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea..."AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
Fwdays
 
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio..."Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
Fwdays
 
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil..."Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
Fwdays
 
"39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment..."39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment...
Fwdays
 
"From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte..."From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte...
Fwdays
 
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
Fwdays
 
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
Fwdays
 
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
Fwdays
 
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake..."Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
Fwdays
 
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest..."Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
Fwdays
 

Recently uploaded (20)

Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 

Михаил Анохин "Data binding 2.0"

  • 1. Data Binding 2.0 Анохин Михаил / Android Developer / MWDN Ltd.
  • 2. Data Binding ● представлен на Google I/O 2015 ● официальная библиотека от Google ● генерирует биндинг во время компиляции ● позволяет реализовать двусторонний биндинг ● доступна стабильная версия 2.1 2
  • 3. public class FindViewByIdFragment 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_simple_as_is, container, false); firstName = (TextView) view.findViewById(R.id.first_name); lastName = (TextView) view.findViewById(R.id.last_name); 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); } } <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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> findViewById 3
  • 4. public class ButterKnifeFragment extends Fragment { @Bind(R.id.first_name) TextView firstName; @Bind(R.id.last_name) TextView lastName; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate( R.layout.fragment_simple_as_is, container, false); ButterKnife.bind(this, view); 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); } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.unbind(this); } } <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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> ButterKnife 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. 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> 6
  • 7. 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; } } 7
  • 8. Configuration android { ... buildToolsVersion "23.0.2" ... dataBinding { enabled = true } ... } buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.0' } } 8
  • 9. Compile-time Generation View view = inflater.inflate(R.layout.fragment_main, container, false); FragmentMainBinding binding = FragmentMainBinding.bind(view); <data class="FragmentMainBinding"> ... </data> <data class=".FragmentMainBinding"> ... </data> <data class="com.example.FragmentMainBinding"> ... </data> 9 Generated classes location: /build/intermediates/classes/{$buildType}/{$applicationId}/databinding
  • 10. Variables and Imports public abstract User getUser(); public abstract void setUser(User user); public abstract Drawable getImage(); public abstract void setImage(Drawable image); public abstract String getText(); public abstract void setText(String text); <data> <import type="android.graphics.drawable.Drawable" /> <import type="com.anokmik.databinding.model.User" /> <variable name="user" type="User" /> <variable name="image" type="Drawable" /> <variable name="text" type="String" /> </data> 10
  • 11. Variables and Imports <data> <import type="android.util.SparseArray"/> <import type="java.util.Map"/> <import type="java.util.List"/> <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> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{titles[0]}" /> <data> <import type="android.app.Fragment"/> <import type="android.support.v4.app.Fragment" alias="SupportFragment"/> </data> 11
  • 12. Data Objects 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
  • 14. 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> 14
  • 15. 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}" 15
  • 17. Null android:text="@{user.firstName ?? user.lastName}" android:text="@{user.firstName != null ? user.firstName : user.lastName}" android:visibility="@{communicator.greeting.name.length > 0 ? View.VISIBLE : View.GONE}" 17
  • 18. Setters and Binding Adapters bind:layoutManager="@{communicator.layoutManager}" 18 android:text="@{user.firstName}" @BindingAdapter("android:text") public static void setText(TextView view, CharSequence text) { ... } android:onTextChanged="@{communicator.onLoginTextChanged}" @BindingAdapter(value = {"android:beforeTextChanged", "android:onTextChanged", "android:afterTextChanged", "android:textAttrChanged"}, requireAll = false) public static void setTextWatcher(TextView view, final BeforeTextChanged before, final OnTextChanged on, final AfterTextChanged after, final InverseBindingListener textAttrChanged) { ... } bind:adapter="@{communicator.adapter}"
  • 19. Data Binding Component 19 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());
  • 20. Binding Methods 20 @BindingMethods({ @BindingMethod(type = View.class, attribute = "android:onDrag", method = "setOnDragListener"), @BindingMethod(type = View.class, attribute = "android:onClick", method = "setOnClickListener"), @BindingMethod(type = View.class, attribute = "android:onTouch", method = "setOnTouchListener"), }) public class ViewBindingAdapter { ... } @BindingMethods({ @BindingMethod(type = TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"), @BindingMethod(type = TextView.class, attribute = "android:inputType", method = "setRawInputType") }) public class TextViewBindingAdapter { ... }
  • 21. Binding Converters public class Converters { @BindingConversion public static String convertObservableToString(ObservableString observableString) { return observableString.get(); } } 21
  • 22. Two Way Binding 22 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}"
  • 23. Two Way Binding 23 @InverseBindingMethods({ @InverseBindingMethod(type = MaterialDesignPrimaryPaletteView.class, attribute = "color") }) public class MaterialDesignPrimaryPaletteView extends GridLayout implements View.OnClickListener { private OnColorChangeListener listener; private int color; ... public int getColor() { return color; } public void setColor(int color) { this.color = color; } public void setOnColorChangeListener(OnColorChangeListener listener) { this.listener = listener; } public interface OnColorChangeListener { void onColorChange(MaterialDesignPrimaryPaletteView view, int color); } }
  • 24. Two Way Binding 24 public class TwoWayDataBindingComponent { @BindingAdapter(value = {"onColorChange", "colorAttrChanged"}, requireAll = false) public void setColorListener(MaterialDesignPrimaryPaletteView view, final OnColorChangeListener listener, final InverseBindingListener colorChange) { if (colorChange == null) { view.setOnColorChangeListener(listener); } else { view.setOnColorChangeListener(new OnColorChangeListener() { @Override public void onColorChange(MaterialDesignPrimaryPaletteView view, int color) { if (listener != null) { listener.onColorChange(view, color); } colorChange.onChange(); } }); } } @BindingAdapter("color") public void setColor(MaterialDesignPrimaryPaletteView view, int color) { if (color != view.getColor()) { view.setColor(color); } } }
  • 25. Lambda Expressions 25 android:onClick="@{() -> communicator.showToast()}" android:onClick="@{() -> communicator.switchState()}" android:onClick="@{(v) -> communicator.replaceFragment(v.id)}"
  • 26. Binding Executor 26 private static final boolean USE_CHOREOGRAPHER = SDK_INT >= 16; ... protected ViewDataBinding(DataBindingComponent bindingComponent, View root, int localFieldCount) { ... if (USE_CHOREOGRAPHER) { mChoreographer = Choreographer.getInstance(); mFrameCallback = new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { mRebindRunnable.run(); } }; } else { mFrameCallback = null; mUIThreadHandler = new Handler(Looper.myLooper()); } }
  • 27. Binding Execution 27 protected void requestRebind() { ... if (USE_CHOREOGRAPHER) { mChoreographer.postFrameCallback(mFrameCallback); } else { mUIThreadHandler.post(mRebindRunnable); } } private final Runnable mRebindRunnable = new Runnable() { @Override public void run() { ... executePendingBindings(); } }; public void executePendingBindings() { ... if (!mRebindHalted) { executeBindings(); ... } ... }
  • 28. Generated Binding 28 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); } } ... }
  • 29. References ● http://developer.android.com/tools/data-binding/guide.html ● https://realm.io/news/data-binding-android-boyar-mount/ ● https://speakerdeck.com/rciovati/binding-data-with-android-databinding ● https://medium.com/@fabioCollini/android-data-binding-f9f9d3afc761 ● https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/ ● https://www.youtube.com/watch?v=ssayKH0tudk ● https://www.youtube.com/watch?v=WdUbXWztKNY ● https://www.youtube.com/watch?v=DAmMN7m3wLU 29
  • 30. Thanks for your attention! source: https://github.com/anokmik/data-binding mail: [email protected] skype: anokmik