Slide 1

Slide 1 text

The Data Binding Library Benoît Quenaudon @oldergod Slides: https://goo.gl/Pr4kjj

Slide 2

Slide 2 text

Problem with Android

Slide 3

Slide 3 text

Problem with Android ● findViewById, Cast textView = (TextView) findViewById(R.id.text_view);

Slide 4

Slide 4 text

Problem with Android ● Setters are complicated and verbose binding.date.setCompoundDrawablesWithIntrinsicBounds(   ContextCompat.getDrawable(this, R.drawable.ic_giants), null, null, null);

Slide 5

Slide 5 text

Problem with Android ● Manually keep track of UI updates textView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged() {} @Override public void onTextChanged() {} @Override public void afterTextChanged() {} });

Slide 6

Slide 6 text

Problem with Android ● Not all setters in Java have XML equivalent textView.setTypeface(); drawerLayout.setScrimColor();

Slide 7

Slide 7 text

Data Binding to the rescue

Slide 8

Slide 8 text

Data Binding Library ? ● A framework to connect your UI and model ○ Once or persistently ● One XML attribute for every Java setter ● Custom XML attributes ● Can override android:’s XML attributes

Slide 9

Slide 9 text

Data Binding Library ? ● A framework to connect your UI and model ○ Once or persistently ● One XML attribute for every Java setter ● Custom XML attributes ● Can override android:’s XML attributes

Slide 10

Slide 10 text

Data Binding Library ? ● A framework to connect your UI and model ○ Once or persistently ● One XML attribute for every Java setter ● Custom XML attributes ● Can override android:’s XML attributes

Slide 11

Slide 11 text

Data Binding Library ? ● A framework to connect your UI and model ○ Once or persistently ● One XML attribute for every Java setter ● Custom XML attributes ● Can override android:’s XML attributes

Slide 12

Slide 12 text

Data Binding Library ? ● A framework to connect your UI and model ○ Once or persistently ● One XML attribute for every Java setter ● Custom XML attributes ● Can override android:’s XML attributes

Slide 13

Slide 13 text

Before / After github.com/oldergod/DataBindingDemo

Slide 14

Slide 14 text

match.xml

Slide 15

Slide 15 text

match.xml

Slide 16

Slide 16 text

match.xml

Slide 17

Slide 17 text

match.xml

Slide 18

Slide 18 text

match.xml

Slide 19

Slide 19 text

match.xml

Slide 20

Slide 20 text

team.xml

Slide 21

Slide 21 text

team.xml

Slide 22

Slide 22 text

team.xml

Slide 23

Slide 23 text

team.xml

Slide 24

Slide 24 text

Setup Data Binding

Slide 25

Slide 25 text

After: build.gradle android { dataBinding { enabled true } }

Slide 26

Slide 26 text

Before: XML After: XML

Slide 27

Slide 27 text

Before: XML After: XML

Slide 28

Slide 28 text

Before: Java setContentView(R.layout.activity_main); After: Java DataBindingUtil.setContentView(this, R.layout.activity_main);

Slide 29

Slide 29 text

Data Binding is ON

Slide 30

Slide 30 text

Now, what can I do?

Slide 31

Slide 31 text

View Binding

Slide 32

Slide 32 text

Before setContentView(R.layout.activity_main); activityList = (ConstraintLayout) findViewById(R.id.activity_list); dateView = (TextView) findViewById(R.id.date); stadiumView = (TextView) findViewById(R.id.stadium); showScoreView = (CheckBox) findViewById(R.id.showScore); scoreView = (TextView) findViewById(R.id.score); bottomNavigationView = (BottomNavigationView)   findViewById(R.id.bottom_navigation); View homeTeam = findViewById(R.id.homeTeam); homeTeamIconView = (ImageView) homeTeam.findViewById(R.id.teamicon); homeTeamNameView = (TextView) homeTeam.findViewById(R.id.teamName); View awayTeam = findViewById(R.id.awayTeam); M O R E

Slide 33

Slide 33 text

After ActivityMainBinding binding =   DataBindingUtil.setContentView(this, R.layout.activity_main);

Slide 34

Slide 34 text

After ActivityMainBinding binding =   DataBindingUtil.setContentView(this, R.layout.activity_main);

Slide 35

Slide 35 text

One way data binding Model → View

Slide 36

Slide 36 text

Before: Java Match match = matchViewModel.getMatch(); scoreView.setText(match.getScore()); After: XML

Slide 37

Slide 37 text

Before: Java Match match = matchViewModel.getMatch(); scoreView.setText(match.getScore()); After: XML

Slide 38

Slide 38 text

Before: Java Match match = matchViewModel.getMatch(); scoreView.setText(match.getScore()); After: XML

Slide 39

Slide 39 text

Before: Java if (match.getStadium() != null) { stadiumView.setText(match.getStadium()); } else { stadiumView.setText(R.string.unknown_stadium); } After: XML

Slide 40

Slide 40 text

Before: Java if (match.getStadium() != null) { stadiumView.setText(match.getStadium()); } else { stadiumView.setText(R.string.unknown_stadium); } After: XML

Slide 41

Slide 41 text

Before: Java if (match.getStadium() != null) { stadiumView.setText(match.getStadium()); } else { stadiumView.setText(R.string.unknown_stadium); } After: XML

Slide 42

Slide 42 text

Before: Java %1$d年%2$d月%3$d日 dateView.setText( getString( R.string.year_date, match.getYear(), match.getMonth(), match.getDay() ) ); After: XML

Slide 43

Slide 43 text

Before: Java %1$d年%2$d月%3$d日 dateView.setText( getString( R.string.year_date, match.getYear(), match.getMonth(), match.getDay() ) ); After: XML

Slide 44

Slide 44 text

Before: Java %1$d年%2$d月%3$d日 dateView.setText( getString( R.string.year_date, match.getYear(), match.getMonth(), match.getDay() ) ); After: XML

Slide 45

Slide 45 text

Before: Java showScoreView.setChecked(match.isShowScore()); After: XML

Slide 46

Slide 46 text

Before: Java scoreView.setVisibility(match.isShowScore() ? VISIBLE : GONE); @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { scoreView.setVisibility(b ? VISIBLE : GONE); } After: XML

Slide 47

Slide 47 text

Before: Java scoreView.setVisibility(match.isShowScore() ? VISIBLE : GONE); @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { scoreView.setVisibility(b ? VISIBLE : GONE); } After: XML

Slide 48

Slide 48 text

Before: Java scoreView.setVisibility(match.isShowScore() ? VISIBLE : GONE); @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { scoreView.setVisibility(b ? VISIBLE : GONE); } After: XML

Slide 49

Slide 49 text

Before: Java scoreView.setVisibility(match.isShowScore() ? VISIBLE : GONE); @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { scoreView.setVisibility(b ? VISIBLE : GONE); } After: XML

Slide 50

Slide 50 text

Before: Java scoreView.setVisibility(match.isShowScore() ? VISIBLE : GONE); @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { scoreView.setVisibility(b ? VISIBLE : GONE); } After: XML

Slide 51

Slide 51 text

Before: Java homeTeamIconView.setImageResource(match.getHomeTeam().getDrawableId()); After: XML

Slide 52

Slide 52 text

Before: Java homeTeamIconView.setImageResource(match.getHomeTeam().getDrawableId()); After: XML

Slide 53

Slide 53 text

Callbacks

Slide 54

Slide 54 text

Before: Java bottomNavigationView.setOnNavigationItemSelectedListener(this); @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) {} After: XML

Slide 55

Slide 55 text

Before: Java bottomNavigationView.setOnNavigationItemSelectedListener(this); @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) {} After: XML

Slide 56

Slide 56 text

Before: Java showScoreView.setOnCheckedChangeListener(this); @Override public void onCheckChanged(CompoundButton compoundButton, boolean b) {} After: XML

Slide 57

Slide 57 text

Model - UI Connection Setup

Slide 58

Slide 58 text

After: XML

Slide 59

Slide 59 text

After: XML

Slide 60

Slide 60 text

After: XML

Slide 61

Slide 61 text

After: XML

Slide 62

Slide 62 text

After: XML

Slide 63

Slide 63 text

After: XML After: Java ActivityMainBinding binding =   DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setMatchVM(matchViewModel); binding.setHandler(this);

Slide 64

Slide 64 text

After: XML After: Java ActivityMainBinding binding =   DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setMatchVM(matchViewModel); binding.setHandler(this);

Slide 65

Slide 65 text

After: XML After: Java ActivityMainBinding binding =   DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setMatchVM(matchViewModel); binding.setHandler(this);

Slide 66

Slide 66 text

After: XML After: Java ActivityMainBinding binding =   DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setMatchVM(matchViewModel); binding.setHandler(this);

Slide 67

Slide 67 text

Slide 68

Slide 68 text

After: XML ... team.xml … match.xml

Slide 69

Slide 69 text

After: XML ... team.xml … match.xml

Slide 70

Slide 70 text

After: XML ... team.xml … match.xml

Slide 71

Slide 71 text

Persistent Binding ModelView changes ⇒ UI updates

Slide 72

Slide 72 text

ViewModel public class MatchViewModel { private Match match; public Match getMatch() { return match; } public void setMatch(Match match) { this.match = match; } }

Slide 73

Slide 73 text

ViewModel public class MatchViewModel extends BaseObservable { private Match match; @Bindable public Match getMatch() { return match; } public void setMatch(Match match) { this.match = match; notifyPropertyChanged(BR.match); } }

Slide 74

Slide 74 text

ViewModel public class MatchViewModel extends BaseObservable { private Match match; @Bindable public Match getMatch() { return match; } public void setMatch(Match match) { this.match = match; notifyPropertyChanged(BR.match); } }

Slide 75

Slide 75 text

ViewModel public class MatchViewModel extends BaseObservable { private Match match; @Bindable public Match getMatch() { return match; } public void setMatch(Match match) { this.match = match; notifyPropertyChanged(BR.match); } }

Slide 76

Slide 76 text

ViewModel public class MatchViewModel extends BaseObservable { private Match match; @Bindable public Match getMatch() { return match; } public void setMatch(Match match) { this.match = match; notifyPropertyChanged(BR.match); } }

Slide 77

Slide 77 text

Two way Binding: Model ↔ View ModelView changes ⇒ UI updates ModelView updates ⇐ UI changes

Slide 78

Slide 78 text

Two way Binding: Model ↔ View ModelView changes ⇒ UI updates ModelView updates ⇐ UI changes

Slide 79

Slide 79 text

Before

Slide 80

Slide 80 text

After

Slide 81

Slide 81 text

After

Slide 82

Slide 82 text

Data Binding Library: How ? ● Zero reflection ● 100% generated Java code ● Bitwise flags to make views dirty

Slide 83

Slide 83 text

Data Binding Library: How ? ● Zero reflection ● 100% generated Java code ● Bitwise flags to make views dirty

Slide 84

Slide 84 text

Data Binding Library: How ? ● Zero reflection ● 100% generated Java code ● Bitwise flags to make views dirty

Slide 85

Slide 85 text

Data Binding Library: How ? ● Zero reflection ● 100% generated Java code ● Bitwise flags to make views dirty

Slide 86

Slide 86 text

Data Binding Library: Generated Code ● from layout/match.xml ● MatchBinding.java ● matchBinding.score ○ MatchBinding.date ○ MatchBinding.team ○ MatchBinding.showScore ○ MatchBinding.bottomNavigationView

Slide 87

Slide 87 text

Data Binding in detail

Slide 88

Slide 88 text

Readibility obj.getAttr() obj.isAttr() obj.hasAttr() ⇒ obj.attr

Slide 89

Slide 89 text

Attributes for every java setter class Team { private int drawableId; public int getDrawableId() {} } class ImageView > void setImageResource (int resId)

Slide 90

Slide 90 text

Attributes for every java setter class Team { private int drawableId; public int getDrawableId() {} } class ImageView > void setImageResource (int resId)

Slide 91

Slide 91 text

Custom XML Attributes @BindingAdapter("imageUrl") public static void loadImage(ImageView view, String url) { Picasso.with(view.getContext()) .load(url) .into(view); }

Slide 92

Slide 92 text

Custom XML Attributes @BindingAdapter("imageUrl") public static void loadImage(ImageView view, String url) { Picasso.with(view.getContext()) .load(url) .into(view); }

Slide 93

Slide 93 text

Java Code Evaluation android:visibility="@{showScore.checked ? View.VISIBLE : View.GONE}" android:padding="@{@dimen/activity_vertical_margin / 2}" android:drawableLeft="@{isCat ? @drawable.cat : @drawable.dog}" android:onClick="@{() -> presenter.onSaveClick(task)}"

Slide 94

Slide 94 text

Null Pointer Exception さようなら if (match != null && match.getHomeTeam() != null) { homeTeamNameView.setText(match.getHomeTeam().getFullname()); }

Slide 95

Slide 95 text

Null Pointer Exception さようなら if (match != null) { homeTeamNameView.setText(match.getHomeTeam().getFullname()); }

Slide 96

Slide 96 text

Null Pointer Exception さようなら if (match != null && match.getHomeTeam() != null) { homeTeamNameView.setText(match.getHomeTeam().getFullname()); } android:text="@{match.team.fullname}"

Slide 97

Slide 97 text

Data Binding と Android Studio

Slide 98

Slide 98 text

Android Studio ● Gradle integration ● Syntax highlighting ● Code completion ● Can view/debug generated code

Slide 99

Slide 99 text

Android Studio ● Gradle integration ● Syntax highlighting ● Code completion ● Can view/debug generated code

Slide 100

Slide 100 text

Android Studio ● Gradle integration ● Syntax highlighting ● Code completion ● Can view/debug generated code

Slide 101

Slide 101 text

Android Studio ● Gradle integration ● Syntax highlighting ● Code completion ● Can view/debug generated code

Slide 102

Slide 102 text

Android Studio ● Gradle integration ● Syntax highlighting ● Code completion ● Can view/debug generated code

Slide 103

Slide 103 text

Android Studio Tips

Slide 104

Slide 104 text

Android Studio Tips ● Put namespaces in

Slide 105

Slide 105 text

Android Studio Tips ● Use tools: for preview

Slide 106

Slide 106 text

Easy to start ● Can be applied to a unique part of your app ● Don’t have to use every feature ○ Only view binding, ○ One way data binding, ○ Custom XML attributes...

Slide 107

Slide 107 text

Data Binding For The Win

Slide 108

Slide 108 text

Want some code? Demo App ● https://github.com/oldergod/DataBindingDemo ○ 0-no-databinding ○ 1-minimal-setup ○ 2-viewbinding ○ 3-oneway-data-binding ○ 4-view-binding-expression ○ 5-binding-adapters ○ 6-persistent-data-binding ○ 7-event-listeners ○ 8-twoway-data-binding

Slide 109

Slide 109 text

No content

Slide 110

Slide 110 text

No content

Slide 111

Slide 111 text

Fin Slides: https://goo.gl/Pr4kjj Benoît Quenaudon @oldergod

Slide 112

Slide 112 text

References ● DataBinding Demo App ○ https://github.com/oldergod/DataBindingDemo ● Data Bindling Library ○ https://developer.android.com/topic/libraries/data-binding/index.html ● talk:title=”@{databinding}” ○ https://www.youtube.com/watch?v=zYGVsTE_scI ● 057: Data Binding with GDE Lisa Wray ○ http://fragmentedpodcast.com/episodes/057/ ● George Mount’s blog posts ○ https://medium.com/@georgemount007