Slide 1

Slide 1 text

Deep dive into Android Data Binding +RadoslawPiekarz @radzio Radosław Piekarz Head of Mobile at Tango Agency

Slide 2

Slide 2 text

droidconde2016 talixo.de 10 € discount

Slide 3

Slide 3 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 4

Slide 4 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 5

Slide 5 text

Setup // /build.gradle apply plugin: "com.android.application" android { dataBinding { enabled = true } }

Slide 6

Slide 6 text

Changes in layout file

Slide 7

Slide 7 text

Changes in Activity / Fragment code @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil .setContentView(this, R.layout.main_activity); binding.myId.setText("John Doe") } Type safe!

Slide 8

Slide 8 text

Binding utils DataBindingUtil.setContentView(activity, layoutId); DataBindingUtil.inflate(inflater, layoutId, parent, attachToParrent); ListItemBinding binding = ListItemBinding.bind(viewRoot); Use for activities Use for any view Bind view that was already inflated

Slide 9

Slide 9 text

Changes in layout file

Slide 10

Slide 10 text

Changes in Activity / Fragment Code @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil .setContentView(this, R.layout.main_activity); binding.setUser(new User()); }

Slide 11

Slide 11 text

Binding expression operators Grouping () Literals character, String, numeric, null Method calls, field access Ternary operator ?: Array access [] Null coalescing operator ?? Mathematical + - / * % String concatenation + Logical && || Binary & | ^ Unary + - ! ~ Shift >> >>> << Comparison == > < >= <= instanceof, cast

Slide 12

Slide 12 text

Binding expression operators android:text="@{user.displayName ?? user.lastName}" android:text="@{user.displayName != null ? user.displayName : user.lastName}" =

Slide 13

Slide 13 text

Notifying view #1 public class User extends BaseObservable { private String firstName; public User(String firstName) { this.firstName = firstName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } @Bindable public String getFirstName() { return this.firstName; } }

Slide 14

Slide 14 text

Notifying view #2 public class User { public final ObservableField firstName; public User(String name) { this.firstName = new ObservableField<>(firstName); } public void setName(String firstName) { this.firstName.set(firstName); } }

Slide 15

Slide 15 text

Observable fields & collections Observable ObservableBoolean ObservableByte ObservableChar ObservableShort ObservableInt ObservableLong ObservableFloat ObservableDouble ObservableParcelable ObservableList ObservableArrayList ObservableMap ObservableArrayMap

Slide 16

Slide 16 text

Binding Adapters @BindingAdapter({"bind:imageUrl", "bind:error"}) public static void loadImage(ImageView view, String url, Drawable error) { Picasso.with(view.getContext()).load(url).error(error).into(view); }

Slide 17

Slide 17 text

Binding Adapters @BindingAdapter({"bind:imageUrl", "bind:error"}) public static void loadImage(ImageView view, String url, Drawable error) { Picasso.with(view.getContext()).load(url).error(error).into(view); }

Slide 18

Slide 18 text

java.lang.IllegalStateException Required DataBindingComponent is null. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.

Slide 19

Slide 19 text

Binding Component public class MyDataBindingCoponent implements DataBindingComponent { public EditTextBindings getEditTextBindings() { return new EditTextBindings(); } }

Slide 20

Slide 20 text

Binding Component @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil .setContentView(this, R.layout.activity_main, new MyDataBindingCoponent()); binding.setViewModel(new ViewModel()); }

Slide 21

Slide 21 text

Binding Conversions android:background="@{isError ? @color/red : @color/white}" @BindingConversion public static ColorDrawable convertColorToDrawable(int color) { return new ColorDrawable(color); }

Slide 22

Slide 22 text

Binding methods @BindingMethods({ @BindingMethod(type = CircularProgressBar.class, attribute = "progressText", method = "setProgressMessage") }) public class ViewBindings { }

Slide 23

Slide 23 text

RecyclerView bindings https://github.com/radzio/android-data-binding-recyclerview

Slide 24

Slide 24 text

Talk is cheap. Show me the code

Slide 25

Slide 25 text

RecyclerView Binding #1

Slide 26

Slide 26 text

RecyclerView Binding #2 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); usersViewModel = new UsersViewModel(); usersViewModel.users .add(new SuperUserViewModel(new User("Android", "Dev"))); binding = DataBindingUtil.setContentView(this, R.layout.users_view); binding.setUsersViewModel(usersViewModel); binding.setView(this); }

Slide 27

Slide 27 text

RecyclerView Binding #3 public class UsersViewModel extends BaseObservable { @Bindable public ObservableArrayList users; public UsersViewModel() { this.users = new ObservableArrayList<>(); } public void addUser(String name, String surname) { this.users.add(new UserViewModel(new User(name, surname))); } }

Slide 28

Slide 28 text

RecyclerView Binding #4 public ItemBinder itemViewBinder() { return new CompositeItemBinder( new SuperUserBinder(BR.user, R.layout.item_super_user), new UserBinder(BR.user, R.layout.item_user) ); }

Slide 29

Slide 29 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 30

Slide 30 text

How it works? Bind ViewModel to View Register for property change callbacks Trigger notifyPropertyChanged Request rebind Execute pending bindings User input or from code

Slide 31

Slide 31 text

How it works? public void setViewModel(TwoWayViewModel viewModel) { updateRegistration(0, viewModel); this.mViewModel = viewModel; synchronized(this) { mDirtyFlags |= 0x1L; notifyPropertyChanged(BR.viewModel); super.requestRebind(); }

Slide 32

Slide 32 text

How it works? @Override protected void executeBindings() { long dirtyFlags = 0; synchronized(this) { dirtyFlags = mDirtyFlags; mDirtyFlags = 0; } if ((dirtyFlags & 0x7L) != 0) { if (viewModel != null) { colorViewModel = viewModel.getColor(); } if ((dirtyFlags & 0x7L) != 0) { ColorPickerViewBindings.setColor(this.colorpicker, colorViewModel); EditTextBindings.setText(this.mboundView2, colorViewModel); } if ((dirtyFlags & 0x4L) != 0) { ColorPickerViewBindings.setColorListener(this.colorpicker, null, colorpickercolorAttr); TextViewBindingAdapter.setTextWatcher(this.mboundView2, null, null, null, mboundView2androidTe); this.mboundView3.setOnClickListener(mCallback2); } }

Slide 33

Slide 33 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 34

Slide 34 text

Lambdas

Slide 35

Slide 35 text

Method References public class MainViewModel extends BaseObservable { public void sendAction(View view) { //code } }

Slide 36

Slide 36 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 37

Slide 37 text

Two-Way data binding ...

Slide 38

Slide 38 text

Two-Way data binding ...

Slide 39

Slide 39 text

Two-Way data binding classpath 'com.android.tools.build:gradle:2.1.0-alpha3'// or above

Slide 40

Slide 40 text

Views with Two-Way Binding support • AbsListView -> 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:progres • TabHost -> android:currentTab • TextView -> android:text • TimePicker -> android:hour, android:minute

Slide 41

Slide 41 text

What about custom views?

Slide 42

Slide 42 text

NO PROBLEM!

Slide 43

Slide 43 text

Two-Way data binding @InverseBindingAdapter(attribute = "color", event = "colorAttrChanged") public static int getColor(ColorPickerView view) { return view.getColor(); } attribute + AttrChanged

Slide 44

Slide 44 text

Activity @BindingAdapter("colorAttrChanged") public static void setColorListener(ColorPickerView view, final InverseBindingListener colorChange) { if (colorChange == null) { view.setOnColorChangedListener(null); } else { view.setOnColorChangedListener(new OnColorChangedListener() { @Override public void onColorChanged(int newColor) { colorChange.onChange(); } }); } }

Slide 45

Slide 45 text

Two-Way data binding @BindingAdapter("color") public static void setColor(ColorPickerView view, int color) { if (color != view.getColor()) { view.setColor(color); } } Avoiding cycles

Slide 46

Slide 46 text

Two-Way data binding public class TwoWayViewModel extends BaseObservable { private int color; public void setColor(int color) { this.color = color; this.notifyPropertyChanged(BR.color); } @Bindable public int getColor() { return this.color; } }

Slide 47

Slide 47 text

Two-Way data binding public class TwoWayBindingActivity extends AppCompatActivity { private ActivityTwoWayBinding binding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_two_way); binding.setViewModel(new TwoWayViewModel()); } }

Slide 48

Slide 48 text

Two-Way data binding

Slide 49

Slide 49 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 50

Slide 50 text

Special Variables Context View IDs

Slide 51

Slide 51 text

Implied Event Updates

Slide 52

Slide 52 text

Repeated expressions

Slide 53

Slide 53 text

Repeated expressions

Slide 54

Slide 54 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 55

Slide 55 text

Dos • From time to time look at generated code • Learn from already implemented bindings for framework views • Move view operations to custom bindings as much as possible • Try to use it together with MVVM design pattern • Give it a chance!

Slide 56

Slide 56 text

Dos • Use Data Binding for backward compatibility!

Slide 57

Slide 57 text

Dos • Always check if data binging library will work with your other libraries (squidb won’t work )

Slide 58

Slide 58 text

Don’ts • Don’t reinvent the wheel, on Github there are many ready to use bindings • Don’t forget about unit tests!

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

Don’ts Don’t move your business logic to xml layout Just don’t!

Slide 61

Slide 61 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 62

Slide 62 text

Say hello to MVVM

Slide 63

Slide 63 text

MVVM & TDD @Mock ISendService sendService; @Test public void mainViewModel_sendAction_sendService_send() { final MainViewModel viewModel = new MainViewModel(sendService); final String givenText = "my text"; viewModel.setTwoWayText(givenText); viewModel.sendAction(); verify(sendService).send(givenText); }

Slide 64

Slide 64 text

Basics How it works? Lambdas Two-Way data binding New stuff announced during Google IO 2016 Dos and don'ts MVVM & TDD Summary

Slide 65

Slide 65 text

Method count • ~700 methods from databinding library • n methods from your custom binding adapters, conversions etc. • k methods from generated code for each layout xml with data binding enabled

Slide 66

Slide 66 text

Summary Cons Compiler errors are sometimes not saying too much Still in beta Documentation is not updated May break other libraries (for example squidb) Pros Easy to start Less boilerplate code Code generation during compilation Easy to integrate with custom views and libraries Really powerful Officialy created and supported by Google Android Team

Slide 67

Slide 67 text

Q&A Q&A https://github.com/radzio/DeepDiveIntoAndroidDataBinding +RadoslawPiekarz @radzio Radosław Piekarz Head of Mobile at Tango Agency