Slide 1

Slide 1 text

A D B ( ) ( ) Xavier Rubio Jansana  @teknik_tdr  https://xrubio.com  https://github.com/xrubioj/

Slide 2

Slide 2 text

W ? Standalone library (no additional dependencies) Compatible with API 7+ (Android 2.1) Announced by Google at I/O 2015 Integrated into Android Studio & Gradle Requires changes to the layouts... simple ones ...but can coexist with old methods → progressive

Slide 3

Slide 3 text

W ? Declarative layouts Minimize code to bind data to layouts Cleaner separation Allows observables (reactive)

Slide 4

Slide 4 text

H ? In app Gradle file: ...if you use Kotlin also add: android { ... dataBinding { enabled = true } } apply plugin: 'kotlin-kapt' ... dependencies { ... kapt "com.android.databinding:compiler:2.3.0" }

Slide 5

Slide 5 text

L

Slide 6

Slide 6 text

L android:id="@+id/message"

Slide 7

Slide 7 text

A class PojoModelActivity : AppCompatActivity() { lateinit var binding: ActivityPojoModelBinding // activity_pojo_model lateinit var model: PojoModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView( this, R.layout.activity_pojo_model) model = PojoModel(message = "Hello World!") binding.model = model } } ActivityPojoModel

Slide 8

Slide 8 text

M

Slide 9

Slide 9 text

M Can be as simple as a POJO or data class If you try to update this model UI will not update: To update we need to replace the whole model: data class PojoModel(var message: String) binding.model.message = "You will never see this" binding.model = PojoModel("But you will see this")

Slide 10

Slide 10 text

M More complex like an Observable You can update individual fields: class ObservableModel() : BaseObservable() { @get:Bindable var message: String? = null set(message) { field = message notifyPropertyChanged(BR.message) } } @get:Bindable notifyPropertyChanged binding.model.message = "You should see this"

Slide 11

Slide 11 text

M Middle ground... ObservableFields You can update individual fields: class ObservableFieldModel() { val message: ObservableField = ObservableField() val visible: ObservableBoolean = ObservableBoolean() constructor(message: String) : this() { this.message.set(message) } } binding.model.message.set("You should see this") set

Slide 12

Slide 12 text

B

Slide 13

Slide 13 text

B Bind variables: in/out Bind views: access views directly Examples var binding: ActivityPojoModelBinding binding.model = PojoModel("Hi!") // binding.text.alpha = 0.5f //

Slide 14

Slide 14 text

B Bind activity layout Bind general layouts val binding: ActivityPojoModelBinding = DataBindingUtil.setContentView( this, R.layout.activity_pojo_model) // or... val binding: ActivityPojoModelBinding = ActivityPojoModelBinding.inflate(layoutInflater) setContentView(binding.root) var binding: ListItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false) // or... var binding: ListItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // ...and finally retrive layout root View binding.root

Slide 15

Slide 15 text

V Expressions are not simple references For example, we can set visibility like this: Null coalescing operator: Null pointer handling: if model is null android:visibility="@{model.visible ? View.VISIBLE : View.GONE}" android:text='@{"This is the message: " + model.message}' android:text='@{model.message ?? "(no message)"}' // equivalent to Elvis operator ?: android:text='@{model.message}' // no crash, evaluates to "(null)" android:visibility="@{model.visible ? View.VISIBLE : View.GONE}" // false => GONE

Slide 16

Slide 16 text

O Java-like expressions: Mathematical + - / * % String concatenation + Logical && || Binary & | ^ Unary + - ! ~ Shi >> >>> << Comparison == > < >= <= instanceof Grouping () Literals - character, String, numeric, null Cast Method calls Field access Array access [] → Collections android:text="@{list[index]}" Ternary operator ?: Method calls

Slide 17

Slide 17 text

S android:text='@{map["firstName"]}' android:text="@{map[`firstName`}" android:text="@{map['firstName']}"

Slide 18

Slide 18 text

T

Slide 19

Slide 19 text

T Allows the binding to update the model For example: Needs a setter on the POJO/data class or Observable Model ⚠ ObservableField doesn't work here (weird compilation error ) =

Slide 20

Slide 20 text

C Allows the binding to convert and format data Simplified conversion ("hackish") ``

Slide 21

Slide 21 text

C Using converters functions IntConverter.INSTANCE.toString object IntConverter { @InverseMethod("toInt") fun toString(value: Int): String { return if (value >= 0) value.toString() else "" } fun toInt(value: String): Int { return try { Integer.parseInt(value) } catch (e: NumberFormatException) { -1 } } } @InverseMethod("toInt")

Slide 22

Slide 22 text

E

Slide 23

Slide 23 text

E Method References → Evaluated at compile time fun onClickButton(view: View) { // ... }

Slide 24

Slide 24 text

E Listener Bindings → Evaluated at run time fun onClickButton(btn: View, data: ItemData) { // ... }

Slide 25

Slide 25 text

C

Slide 26

Slide 26 text

C Creation of the layout Doesn't find new binding on first usage → Build→Clean Project

Slide 27

Slide 27 text

C Annotation processor errors and kapt Not very useful → Check Gradle Console

Slide 28

Slide 28 text

C Error messages in Gradle Console lines are off-by-1 It is really line 47, column 30 e: java.lang.IllegalStateException: failed to analyze: java.lang.RuntimeException: Found data binding errors. ****/ data binding error ****msg:Cannot resolve type for IntConverter file:/Users/teknik/Documents/source/ _talks/android-data-binding-talk/databinding-example/app/src/main/res/layout/ activity_two_way_binding_conversion_converter.xml loc:46:29 - 46:62 ****\ data binding error **** 46:29

Slide 29

Slide 29 text

R Google's Data Binding Library George Mount Medium articles Android Data Binding In Practice https://developer.android.com/topic/libraries/data- binding/index.html https://medium.com/@georgemount007 https://truveris.github.io/articles/android- advanced-data-binding/

Slide 30

Slide 30 text

Q ?

Slide 31

Slide 31 text

T ! Xavier Rubio Jansana This talk is available at:  @teknik_tdr  https://xrubio.com  https://github.com/xrubioj/ https://xrubio.com/talks/talk-android-data-binding-from-null-to-data/