Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f12c00de authored by Hemal Patel's avatar Hemal Patel Committed by android-build-merger
Browse files

Merge \\"Docs: Completed updates to the Data Binding docs\\" into mnc-io-docs am: eebe22fe

am: f693ea68

Change-Id: I235e73606098e54fc14568c6437af314f9bea337
parents 2756d070 f693ea68
Loading
Loading
Loading
Loading
+190 −45
Original line number Diff line number Diff line
@@ -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
&mdash; 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>
&lt;<strong>variable name="user" type="com.example.User"</strong>/&gt;
</pre>
<p>
  Expressions within the layout are written in the attribute properties using
  the “<code>&commat;{}</code>” syntax. Here, the TextView’s text is set to the
  firstName property of user:
  the “<code>&amp;commat;{}</code>” syntax. Here, the TextView’s text is set to
  the firstName property of user:
</p>

<pre>
&lt;TextView android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="&commat;{user.firstName}"/&gt;
          android:text="&amp;commat;{user.firstName}"/&gt;
</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>&commat;{user.firstName}</code></strong> used for
  the TextView’s <strong><code>android:text</code></strong> attribute will
  expression <strong><code>&amp;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.
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
       &lt;TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="&commat;{user.firstName}"
           android:onClick="&commat;{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/&gt;
       &lt;TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="&commat;{user.lastName}"
           android:onClick="&commat;{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/&gt;
           android:onClick="&commat;{handlers::onClickFriend}"/&gt;
   &lt;/LinearLayout&gt;
&lt;/layout&gt;
</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>
  &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
      &lt;data&gt;
          &lt;variable name=&quot;task&quot; type=&quot;com.android.example.Task&quot; /&gt;
          &lt;variable name=&quot;presenter&quot; type=&quot;com.android.example.Presenter&quot; /&gt;
      &lt;/data&gt;
      &lt;LinearLayout android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;match_parent&quot;&gt;
          &lt;Button android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
          android:onClick=&quot;@{() -&gt; presenter.onSaveClick(task)}&quot; /&gt;
      &lt;/LinearLayout&gt;
  &lt;/layout&gt;
</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=&quot;@{(view) -&gt; presenter.onSaveClick(task)}&quot;
</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=&quot;@{(theView) -&gt; presenter.onSaveClick(theView, task)}&quot;
</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>
  &lt;CheckBox android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
        android:onCheckedChanged=&quot;@{(cb, isChecked) -&gt; presenter.completeChanged(task, isChecked)}&quot; /&gt;
</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=&quot;@{(theView) -&gt; presenter.onLongClick(theView, task)}&quot;
</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=&quot;@{(v) -&gt; v.isVisible() ? doSomething() : void}&quot;
</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