diff options
| author | 2016-06-17 18:35:50 +0000 | |
|---|---|---|
| committer | 2016-06-17 18:35:51 +0000 | |
| commit | 68bfdd71b57894fcdf0ace40db394bbb4a43b0b5 (patch) | |
| tree | f2039a89c14d16b80fc0c146bd376333039deadf | |
| parent | 9f0722a4c77a305ac9ec3e436b86d9f4ee9aedbf (diff) | |
| parent | f12c00dea467673897ccc444c5448ab2d4a11098 (diff) | |
Merge "Merge \\"Docs: Completed updates to the Data Binding docs\\" into mnc-io-docs am: eebe22fef6 am: f693ea687f" into nyc-dev
| -rw-r--r-- | docs/html/topic/libraries/data-binding/index.jd | 235 |
1 files changed, 190 insertions, 45 deletions
diff --git a/docs/html/topic/libraries/data-binding/index.jd b/docs/html/topic/libraries/data-binding/index.jd index ca8784ebfcfb..293de51ea000 100644 --- a/docs/html/topic/libraries/data-binding/index.jd +++ b/docs/html/topic/libraries/data-binding/index.jd @@ -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 |