Merge \"Docs: Completed updates to the Data Binding docs\" into mnc-io-docs
am: eebe22fef6
Change-Id: I47b4003b1bd1bb5cdfc12bde543dd2c9d8babdcc
This commit is contained in:
@ -18,7 +18,7 @@ page.tags="databinding", "layouts"
|
||||
<a href="#data_binding_layout_files">Data Binding Layout Files</a>
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#writing_expressions">Writing your first data binding
|
||||
<a href="#writing_expressions">Writing your first set of data binding
|
||||
expressions</a>
|
||||
</li>
|
||||
|
||||
@ -29,9 +29,16 @@ page.tags="databinding", "layouts"
|
||||
<li>
|
||||
<a href="#binding_data">Binding Data</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#binding_events">Binding Events</a>
|
||||
<a href="#event_handling">Event Handling</a>
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#method_references">Method References</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#listener_bindings">Listener Bindings</a>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
@ -147,27 +154,34 @@ page.tags="databinding", "layouts"
|
||||
application logic and layouts.
|
||||
</p>
|
||||
|
||||
<p>The Data Binding Library offers both flexibility and broad compatibility
|
||||
— it's a support library, so you can use it with all Android platform
|
||||
versions back to <strong>Android 2.1</strong> (API level 7+).</p>
|
||||
<p>
|
||||
The Data Binding Library offers both flexibility and broad compatibility —
|
||||
it's a support library, so you can use it with all Android platform versions
|
||||
back to <strong>Android 2.1</strong> (API level 7+).
|
||||
</p>
|
||||
|
||||
<p>To use data binding, Android Plugin for Gradle <strong>1.5.0-alpha1</strong>
|
||||
or higher is required.</p>
|
||||
<p>
|
||||
To use data binding, Android Plugin for Gradle <strong>1.5.0-alpha1</strong>
|
||||
or higher is required.
|
||||
</p>
|
||||
|
||||
<h2 id="build_environment">
|
||||
Build Environment
|
||||
</h2>
|
||||
|
||||
<p>To get started with Data Binding, download the library from the Support
|
||||
repository in the Android SDK manager. </p>
|
||||
|
||||
<p>
|
||||
To configure your app to use data binding, add the <code>dataBinding</code> element to your
|
||||
<code>build.gradle</code> file in the app module.
|
||||
To get started with Data Binding, download the library from the Support
|
||||
repository in the Android SDK manager.
|
||||
</p>
|
||||
|
||||
<p>Use the following code snippet to configure data binding: </p>
|
||||
<p>
|
||||
To configure your app to use data binding, add the <code>dataBinding</code>
|
||||
element to your <code>build.gradle</code> file in the app module.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Use the following code snippet to configure data binding:
|
||||
</p>
|
||||
<pre>
|
||||
android {
|
||||
....
|
||||
@ -176,13 +190,17 @@ android {
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
If you have an app module that depends on a library which uses data binding,
|
||||
your app module must configure data binding in its <code>build.gradle</code>
|
||||
file as well.
|
||||
</p>
|
||||
|
||||
<p>If you have an app module that depends on a library which uses data binding, your app module
|
||||
must configure data binding in its <code>build.gradle</code> file as well.</p>
|
||||
|
||||
<p>Also, make sure you are using a compatible version of Android Studio.
|
||||
<strong>Android Studio 1.3</strong> and later provides support for data binding as described in
|
||||
<a href="#studio_support">Android Studio Support for Data Binding</a>.
|
||||
<p>
|
||||
Also, make sure you are using a compatible version of Android Studio.
|
||||
<strong>Android Studio 1.3</strong> and later provides support for data
|
||||
binding as described in <a href="#studio_support">Android Studio Support for
|
||||
Data Binding</a>.
|
||||
</p>
|
||||
|
||||
<h2 id="data_binding_layout_files">
|
||||
@ -190,7 +208,7 @@ android {
|
||||
</h2>
|
||||
|
||||
<h3 id="writing_expressions">
|
||||
Writing your first data binding expressions
|
||||
Writing your first set of data binding expressions
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
@ -223,20 +241,19 @@ android {
|
||||
The user <strong>variable</strong> within <strong>data</strong> describes a
|
||||
property that may be used within this layout.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<<strong>variable name="user" type="com.example.User"</strong>/>
|
||||
</pre>
|
||||
<p>
|
||||
Expressions within the layout are written in the attribute properties using
|
||||
the “<code>@{}</code>” syntax. Here, the TextView’s text is set to the
|
||||
firstName property of user:
|
||||
the “<code>&commat;{}</code>” syntax. Here, the TextView’s text is set to
|
||||
the firstName property of user:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{user.firstName}"/>
|
||||
android:text="&commat;{user.firstName}"/>
|
||||
</pre>
|
||||
<h3 id="data_object">
|
||||
Data Object
|
||||
@ -261,7 +278,6 @@ public class User {
|
||||
to have data that is read once and never changes thereafter. It is also
|
||||
possible to use a JavaBeans objects:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
public class User {
|
||||
private final String firstName;
|
||||
@ -280,11 +296,12 @@ public class User {
|
||||
</pre>
|
||||
<p>
|
||||
From the perspective of data binding, these two classes are equivalent. The
|
||||
expression <strong><code>@{user.firstName}</code></strong> used for
|
||||
the TextView’s <strong><code>android:text</code></strong> attribute will
|
||||
expression <strong><code>&commat;{user.firstName}</code></strong> used
|
||||
for the TextView’s <strong><code>android:text</code></strong> attribute will
|
||||
access the <strong><code>firstName</code></strong> field in the former class
|
||||
and the <code>getFirstName()</code> method in the latter class. Alternatively, it
|
||||
will also be resolved to <code>firstName()</code> if that method exists.
|
||||
and the <code>getFirstName()</code> method in the latter class.
|
||||
Alternatively, it will also be resolved to <code>firstName()</code> if that
|
||||
method exists.
|
||||
</p>
|
||||
|
||||
<h3 id="binding_data">
|
||||
@ -328,16 +345,38 @@ ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, fal
|
||||
//or
|
||||
ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.layout.<em><strong>list_item</strong></em>, viewGroup, <strong>false</strong>);
|
||||
</pre>
|
||||
|
||||
<h3 id="binding_events">
|
||||
Binding Events
|
||||
</h3>
|
||||
<h3 id="event_handling">Event Handling</h3>
|
||||
<p>
|
||||
Events may be bound to handler methods directly, similar to the way
|
||||
<strong><code>android:onClick</code></strong> can be assigned to a method in the Activity.
|
||||
Event attribute names are governed by the name of the listener method with a few exceptions.
|
||||
For example, {@link android.view.View.OnLongClickListener} has a method {@link android.view.View.OnLongClickListener#onLongClick onLongClick()},
|
||||
so the attribute for this event is <code>android:onLongClick</code>.
|
||||
Data Binding allows you to write expressions handling events that are dispatched from the views (e.g. onClick).
|
||||
Event attribute names are governed by the name of the listener method with a few exceptions.
|
||||
For example, {@link android.view.View.OnLongClickListener} has a method {@link android.view.View.OnLongClickListener#onLongClick onLongClick()},
|
||||
so the attribute for this event is <code>android:onLongClick</code>.
|
||||
There are two ways to handle an event.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#method_references">Method References</a>: In your expressions, you can reference methods that conform to the signature of the listener method. When an expression evaluates to a method reference, Data Binding wraps the method reference and owner object in a listener, and sets that listener on the target view. If the expression evaluates to null, Data Binding does not create a listener and sets a null listener instead.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#listener_bindings">Listener Bindings</a>: These are lambda expressions that are evaluated when the event happens.
|
||||
Data Binding always creates a listener, which it sets on the view. When the event is dispatched, the listener evaluates the lambda expression.
|
||||
</li>
|
||||
</ul>
|
||||
<h4 id="method_references">
|
||||
Method References
|
||||
</h4>
|
||||
<p>
|
||||
Events can be bound to handler methods directly, similar to the way
|
||||
<strong><code>android:onClick</code></strong> can be assigned to a method in an Activity.
|
||||
One major advantage compared to the {@code View#onClick} attribute is that the expression
|
||||
is processed at compile time, so if the method does not exist or its signature is not
|
||||
correct, you receive a compile time error.</p>
|
||||
<p>
|
||||
The major difference between Method References and Listener Bindings is that
|
||||
the actual listener implementation is created when the data is bound, not
|
||||
when the event is triggered. If you prefer to evaluate the expression when
|
||||
the event happens, you should use <a href="#listener_bindings">listener
|
||||
binding</a>.
|
||||
</p>
|
||||
<p>
|
||||
To assign an event to its handler, use a normal binding expression, with the value
|
||||
@ -345,7 +384,6 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay
|
||||
</p>
|
||||
<pre>public class MyHandlers {
|
||||
public void onClickFriend(View view) { ... }
|
||||
public void onClickEnemy(View view) { ... }
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
@ -365,14 +403,121 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{user.firstName}"
|
||||
android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{user.lastName}"
|
||||
android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/>
|
||||
android:onClick="@{handlers::onClickFriend}"/>
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
</pre>
|
||||
<p>
|
||||
Note that the signature of the method in the expression must exactly match the signature of the method in the
|
||||
Listener object.
|
||||
</p>
|
||||
<h4 id="listener_bindings">
|
||||
Listener Bindings
|
||||
</h4>
|
||||
<p>
|
||||
Listener Bindings are binding expressions that run when an event happens.
|
||||
They are similar to method references, but they let you run arbitrary data
|
||||
binding expressions. This feature is available with Android Gradle Plugin for Gradle
|
||||
version 2.0 and later.
|
||||
</p>
|
||||
<p>
|
||||
In method references, the parameters of the method must
|
||||
match the parameters of the event listener. In Listener Bindings, only your
|
||||
return value must match the expected return value of the listener (unless it
|
||||
is expecting void).
|
||||
For example, you can have a presenter class that has the following method:
|
||||
</p>
|
||||
<pre>
|
||||
public class Presenter {
|
||||
public void onSaveClick(Task task){}
|
||||
}
|
||||
</pre>
|
||||
Then you can bind the click event to your class as follows:
|
||||
<pre>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<data>
|
||||
<variable name="task" type="com.android.example.Task" />
|
||||
<variable name="presenter" type="com.android.example.Presenter" />
|
||||
</data>
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:onClick="@{() -> presenter.onSaveClick(task)}" />
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
</pre>
|
||||
<p>
|
||||
Listeners are represented by lambda expressions that are allowed only as root
|
||||
elements of your expressions. When a callback is used in an expression, Data
|
||||
Binding automatically creates the necessary listener and registers for the
|
||||
event. When the view fires the event, Data Binding evaluates the given
|
||||
expression. As in regular binding expressions, you still get the null and
|
||||
thread safety of Data Binding while these listener expressions are being
|
||||
evaluated.
|
||||
</p>
|
||||
<p>
|
||||
Note that in the example above, we haven't defined the {@code view} parameter
|
||||
that is passed into {@link
|
||||
android.view.View.OnClickListener#onClick(android.view.View view)}. Listener
|
||||
bindings provide two choices for listener parameters: you can either ignore
|
||||
all parameters to the method or name all of them. If you prefer to name the
|
||||
parameters, you can use them in your expression. For example, the expression
|
||||
above could be written as:
|
||||
</p>
|
||||
<pre>
|
||||
android:onClick="@{(view) -> presenter.onSaveClick(task)}"
|
||||
</pre>
|
||||
Or if you wanted to use the parameter in the expression, it could work as follows:
|
||||
<pre>
|
||||
public class Presenter {
|
||||
public void onSaveClick(View view, Task task){}
|
||||
}
|
||||
</pre>
|
||||
<pre>
|
||||
android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
|
||||
</pre>
|
||||
You can use a lambda expression with more than one parameter:
|
||||
<pre>
|
||||
public class Presenter {
|
||||
public void onCompletedChanged(Task task, boolean completed){}
|
||||
}
|
||||
</pre>
|
||||
<pre>
|
||||
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
|
||||
</pre>
|
||||
<p>
|
||||
If the event you are listening to returns a value whose type is not {@code
|
||||
void}, your expressions must return the same type of value as well. For
|
||||
example, if you want to listen for the long click event, your expression
|
||||
should return {@code boolean}.
|
||||
</p>
|
||||
<pre>
|
||||
public class Presenter {
|
||||
public boolean onLongClick(View view, Task task){}
|
||||
}
|
||||
</pre>
|
||||
<pre>
|
||||
android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"
|
||||
</pre>
|
||||
<p>
|
||||
If the expression cannot be evaluated due to {@code null} objects, Data Binding returns
|
||||
the default Java value for that type. For example, {@code null} for reference types, {@code 0} for {@code int},
|
||||
{@code false} for {@code boolean}, etc.
|
||||
</p>
|
||||
<p>
|
||||
If you need to use an expression with a predicate (e.g. ternary), you can use
|
||||
{@code void} as a symbol.
|
||||
</p>
|
||||
<pre>
|
||||
android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
|
||||
</pre>
|
||||
|
||||
<h5>Avoid Complex Listeners</h5>
|
||||
Listener expressions are very powerful and can make your code very easy to read.
|
||||
On the other hand, listeners containing complex expressions make your layouts hard to read and unmaintainable.
|
||||
These expressions should be as simple as passing available data from your UI to your callback method. You should implement
|
||||
any business logic inside the callback method that you invoked from the listener expression.
|
||||
|
||||
<p>
|
||||
Some specialized click event handlers exist and they need an attribute other than
|
||||
|
Reference in New Issue
Block a user