[MUSIC PLAYING]
DAN GALPIN: Level up with data binding.
All right, so when data binding was introduced back in 2015--
and I can't read anything so I'll just do it from here--
my reaction was pretty much, what have we done?
Like expressions inside of XML values-- this is kind of nuts.
But, as it turns out, data binding is pretty cool.
And I just needed to level up my understanding.
And the one thing I love about data binding
is you can actually choose how much of it you wanted to use.
So at the beginner level, you get some immediate benefits,
like avoiding FindViewById.
But that's a start.
At the intermediate level, you actually
get things like custom binding adapters
and observability, while, at the expert level,
we actually have two-way data binding.
And this also allows you to apply observability,
not only from data to UI, but also from UI to data.
So, first of all, let's get rid of FindViewById.
[CHEERS]
Exactly.
So first we need to enable data binding.
Now all you have to do to do this is actually
set data binding enabled equals true in your Gradle file.
And then you need to put these little layout
wrappers around your file.
And you can actually do that in Android Studio
automatically now by pulling down from the little light bulb
icon and saying convert to data binding layout, which
is pretty cool.
Now the binding is actually this object
you get from inflating the layout with data binding util.
And you simply set your attributes and listeners
like this, which is pretty cool.
But, honestly, you're never going
to use this because you're actually
going to want to use real data binding.
So let's talk about binding expressions.
And, in order to do this, we actually
have to make data available to our layout
by declaring variables in this data section of our layout.
And then we can use expressions in layout XML attributes
to actually tie that data to views.
Now expressions are actually wrapped in curly braces
and prefixed by an @ sign.
So here are some examples of data binding expressions.
Again, this first one we're assigning a text property
to a view model property.
In the second one, we're using a custom attribute-- height of 0.
And in the third one we're actually
using a lambda, which gets past the text view
and calls on like.
And in this fourth one, we're actually
using a lambda, which calls on like with a text property
of another view in our layout.
So you can actually reference other views
and pass them in, which is pretty cool.
Now, to give data binding access to the ViewModel engines,
we just set the binding object like this
after inflating the layout.
So pretty straightforward.
And then our view model is now available to that layout.
But the real question is, how does this all work?
And the answer, of course, is that there
is no magic in data binding.
But it does seem like magic.
And that's because we have built-in binding adapters that
handle almost everything.
So with data binding every call to the framework
is actually made in a binding adapter.
There's no magic.
You can actually see the coding, use a debugger
to navigate through it.
The first lines of the method are just
checking for changes to only update the UI if necessary.
And that last line is actually the set text we're looking for.
And there's lots of adapter provided by data binding.
And they make it behave intelligently and consistently
across all these views.
Now looking at these source files
will help to build your own custom
binding adapters, which is really how
things start to get exciting.
So let's talk about binding adapters 101.
The adapters annotated with @BindingAdapter
and takes one or more attribute names.
The adapter method takes a view as the first parameter
and you use a subclass of view to restrict it
to a specific view type.
Any additional parameters are then
matched with the data side of the binding expressions.
Adapters can differ just by data types.
You can also use adapters to override the behavior
for built-in attributes.
Now this makes all image use load
using glide with their source parameters set.
But you've got to careful with this
because this is module global.
So you might have some really cool side effects
of this you might not expect.
We also could do a bunch of stuff
with advanced binding adapters.
So sometimes that old value is really important,
such as with a color change listener.
So if you use the same parameter type
for two parameters in a row, the binding compiler actually
passed the old value into the first one
followed by the updated one.
And also you can use multiple attributes, which is pretty
cool, like in this image view.
So you can actually define these multiple attributes here
when you declare the binding adapter.
And then those are both available to your code,
actually, as you're looking at it.
Now observability is also pretty cool.
And we can actually use LiveData to automatically do
observation.
So this is pretty cool.
We're actually only exposing an immutable class here,
with an example of this.
And the backing field can either be a mutable or mediator
LiveData.
And then you just expose the LiveData
using Kotlin getters attacks.
And then you need to do one more additional change.
You actually need to set the lifecycle owner.
So you can observe the LiveData in your view model
with the correct scope.
All right.
Finally, two-way data binding.
And, honestly, this is really trivial
when you're actually using LiveData.
Now you could, of course, use one-way data binding two ways,
as in this example of checkbox.
But you could actually call this with two-way data binding
by using @=.
And the best part of this is we can actually observe LiveData.
So, in this case, it's fine to expose immutable LiveData,
since it's going to be modified by our view.
And then we set the lifecycle owner and we use the @=
notation for the checkbox.
And that's it-- two-way data binding.
Maybe that's not so expert after all.
So to learn more, check out the data
binding code lab and the documentation
on developer.Android.com.
[MUSIC PLAYING]