For the More Curious: More About Data Binding

Complete coverage of data binding is outside the scope of this book. And yet, reader, we must nevertheless try.

Lambda expressions

You can write short callbacks directly in your layout file by using lambda expressions. These are simplified versions of Java’s lambda expressions:

<Button
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:text="@{viewModel.title}"
    android:onClick="@{(view) -> viewModel.onButtonClick()}"
    tools:text="Sound name"/>

Like Java 8 lambda expressions, these are turned into implementations for the interface you use them for. (In this case, View.OnClickListener.) Unlike Java 8 lambda expressions, these expressions must use this exact syntax: The parameter must be in parentheses, and you must have exactly one expression on the right-hand side.

Also, unlike in Java lambdas, you can omit the lambda parameters if you are not using them. So this works fine, too:

    android:onClick="@{() -> viewModel.onButtonClick()}"

More syntactic sugar

You also get a few additional bits of handy syntax for data binding. Particularly handy is the ability to use backticks for double quotes:

    android:text="@{`File name: ` + viewModel.title}"

Here, `File name` means the same thing as "File name".

Binding expressions also have a null coalescing operator:

    android:text="@{`File name: ` + viewModel.title ?? `No file`}"

In the event that title is null, the ?? operator will yield the value "No file" instead.

In addition, there is automatic null handling provided for you in data binding. Even if viewModel is null in the code above, data binding will provide appropriate null checks so that it does not crash the app. Instead of crashing, the subexpression viewModel.title will yield "null".

BindingAdapters

By default, data binding interprets a binding expression as a property invocation. So the following:

    android:text="@{`File name: ` + viewModel.title ?? `No file`}"

is translated into an invocation of the setText(String) method.

Sometimes, though, that is not enough, and you want some custom behavior to be applied for a particular attribute. In those cases, you can write a BindingAdapter:

public class BeatBoxBindingAdapter {
    @BindingAdapter("app:soundName")
    public static void bindAssetSound(Button button, String assetFileName) {
        ...
    }
}

Simply create a static method in any class in your project and annotate it with @BindingAdapter, passing in the name of the attribute you want to bind as a parameter. (Yes, this really works.) Whenever data binding needs to apply that attribute, it will call your static method.

You will probably think of one or two operations you would like to use data binding with on the standard library widgets. Many common operations already have binding adapters defined – for example, TextViewBindingAdapter provides additional attributes for TextView. You can read these binding adapters yourself by viewing the source in Android Studio. So, before you write your own solution, type Command+Shift+O (Ctrl+Shift+O) to search for a class, open up the associated binding adapters file, and check to see whether it already exists.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.60.35