[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]
