Home | History | Annotate | Download | only in data-binding
      1 page.title=Data Binding Guide
      2 page.tags="databinding", "layouts"
      3 @jd:body
      4 
      5 <div id="qv-wrapper">
      6   <div id="qv">
      7     <h2>
      8       In this document:
      9     </h2>
     10 
     11     <ol>
     12       <li>
     13         <a href="#build_environment">Build Environment</a>
     14       </li>
     15 
     16       <li>
     17         <a href="#data_binding_layout_files">Data Binding Layout Files</a>
     18         <ol>
     19           <li>
     20             <a href="#writing_expressions">Writing your first data binding
     21             expressions</a>
     22           </li>
     23 
     24           <li>
     25             <a href="#data_object">Data Object</a>
     26           </li>
     27 
     28           <li>
     29             <a href="#binding_data">Binding Data</a>
     30           </li>
     31 
     32           <li>
     33             <a href="#binding_events">Binding Events</a>
     34           </li>
     35         </ol>
     36       </li>
     37 
     38       <li>
     39         <a href="#layout_details">Layout Details</a>
     40         <ol>
     41           <li>
     42             <a href="#imports">Imports</a>
     43           </li>
     44 
     45           <li>
     46             <a href="#variables">Variables</a>
     47           </li>
     48 
     49           <li>
     50             <a href="#custom_binding_class_names">Custom Binding Class Names</a>
     51           </li>
     52 
     53           <li>
     54             <a href="#includes">Includes</a>
     55           </li>
     56 
     57           <li>
     58             <a href="#expression_language">Expression Language</a>
     59           </li>
     60         </ol>
     61       </li>
     62 
     63       <li>
     64         <a href="#data_objects">Data Objects</a>
     65         <ol>
     66           <li>
     67             <a href="#observable_objects">Observable Objects</a>
     68           </li>
     69 
     70           <li>
     71             <a href="#observablefields">ObservableFields</a>
     72           </li>
     73 
     74           <li>
     75             <a href="#observable_collections">Observable Collections</a>
     76           </li>
     77         </ol>
     78       </li>
     79 
     80       <li>
     81         <a href="#generated_binding">Generated Binding</a>
     82         <ol>
     83           <li>
     84             <a href="#creating">Creating</a>
     85           </li>
     86 
     87           <li>
     88             <a href="#views_with_ids">Views With IDs</a>
     89           </li>
     90 
     91           <li>
     92             <a href="#variables">Variables</a>
     93           </li>
     94 
     95           <li>
     96             <a href="#viewstubs">ViewStubs</a>
     97           </li>
     98 
     99           <li>
    100             <a href="#advanced_binding">Advanced Binding</a>
    101           </li>
    102         </ol>
    103       </li>
    104 
    105       <li>
    106         <a href="#attribute_setters">Attribute Setters</a>
    107         <ol>
    108           <li>
    109             <a href="#automatic_setters">Automatic Setters</a>
    110           </li>
    111 
    112           <li>
    113             <a href="#renamed_setters">Renamed Setters</a>
    114           </li>
    115 
    116           <li>
    117             <a href="#custom_setters">Custom Setters</a>
    118           </li>
    119         </ol>
    120       </li>
    121 
    122       <li>
    123         <a href="#converters">Converters</a>
    124         <ol>
    125           <li>
    126             <a href="#object_conversions">Object Conversions</a>
    127           </li>
    128 
    129           <li>
    130             <a href="#custom_conversions">Custom Conversions</a>
    131           </li>
    132         </ol>
    133       </li>
    134     </ol>
    135   </div><!-- qv -->
    136 </div><!-- qv-wrapper -->
    137 
    138 <p>
    139   This document explains how to use the Data Binding Library to write
    140   declarative layouts and minimize the glue code necessary to bind your
    141   application logic and layouts.
    142 </p>
    143 
    144 <p>The Data Binding Library offers both flexibility and broad comnpatibility
    145 &mdash; it's a support library, so you can use it with all Android platform
    146 versions back to <strong>Android 2.1</strong> (API level 7+).</p>
    147 
    148 <p>To use data binding, Android Plugin for Gradle <strong>1.3.0-beta4</strong>
    149 or higher is required.</p>
    150 
    151 <h4>Beta release</h4>
    152 
    153 <div class="caution">
    154   <p>Please note that the Data Binding library is a <strong>beta release</strong>.
    155   While Data Binding is in beta, developers should be aware of the following
    156   caveats:</p>
    157   <ul>
    158     <li>
    159     This is a beta release of the feature intended to generate developer
    160     feedback. It might contain bugs, and it might not work for your use case,
    161     so use it at your own risk. That said, we do want your feedback! Please
    162     let us know what is or isnt working for you using the <a
    163     href="https://code.google.com/p/android-developer-preview/">issue
    164     tracker</a>.
    165     </li>
    166     <li>
    167     The Data Binding library beta release is subject to significant changes,
    168     including those which are not source code compatible with your app. That is,
    169     significant rework may be required to take updates to the library in the future.
    170     </li>
    171     <li>
    172     Developers should feel free to publish apps built with the Data Binding
    173     library beta release, with the caveats that the standard Android SDK and
    174     Google Play terms of service apply, and its always a great idea to test your
    175     app thoroughly when adopting new libraries or tools.
    176     </li>
    177     <li>
    178     Were just getting started with Android Studio support at this time.
    179     Further Android Studio support will come in the future.
    180     </li>
    181     <li>
    182     By using the Data Binding library beta release, you acknowledge these
    183     caveats.</li>
    184   </ul>
    185 </div>
    186 
    187 <h2 id="build_environment">
    188   Build Environment
    189 </h2>
    190 
    191 <p>To get started with Data Binding, download the library from the Support
    192 repository in the Android SDK manager. </p>
    193 
    194 <p>The Data Binding plugin requires Android Plugin for Gradle <strong>1.3.0-beta4
    195 or higher</strong>, so update your build dependencies (in the top-level
    196 <code>build.gradle</code> file) as needed.</p>
    197 
    198 <p>Also, make sure you are using a compatible version of Android Studio.
    199 <strong>Android Studio 1.3</strong> adds the code-completion and layout-preview
    200 support for data binding.</p>
    201 
    202 <p>
    203   <strong>Setting Up Work Environment:</strong>
    204 </p>
    205 
    206 <p>
    207   To set up your application to use data binding, add data binding to the class
    208   path of your top-level <code>build.gradle</code> file, right below "android".
    209 </p>
    210 
    211 <pre>
    212    dependencies {
    213        classpath <strong>"com.android.tools.build:gradle:1.3.0-beta4"</strong>
    214        classpath <strong>"com.android.databinding:dataBinder:1.0-rc1"</strong>
    215    }
    216 </pre>
    217 <p>
    218   Then make sure jcenter is in the repositories list for your projects in the top-level
    219   <code>build.gradle</code> file.
    220 </p>
    221 
    222 <pre>
    223 allprojects {
    224    repositories {
    225        jcenter()
    226    }
    227 }
    228 </pre>
    229 <p>
    230   In each module you want to use data binding, apply the plugin right after
    231   android plugin
    232 </p>
    233 
    234 <pre>
    235 apply plugin: &apos;com.android.application&apos;
    236 apply plugin: &apos;com.android.databinding&apos;
    237 </pre>
    238 <p>
    239   The data binding plugin is going to add necessary <strong>provided</strong>
    240   and <strong>compile configuration</strong> dependencies to your project.
    241 </p>
    242 
    243 <h2 id="data_binding_layout_files">
    244   Data Binding Layout Files
    245 </h2>
    246 
    247 <h3 id="writing_expressions">
    248   Writing your first data binding expressions
    249 </h3>
    250 
    251 <p>
    252   Data-binding layout files are slightly different and start with a root tag of
    253   <strong>layout</strong> followed by a <strong>data</strong> element and a
    254   <strong>view</strong> root element. This view element is what your root would
    255   be in a non-binding layout file. A sample file looks like this:
    256 </p>
    257 
    258 <pre>
    259 &lt;?xml version="1.0" encoding="utf-8"?&gt;
    260 &lt;layout xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    261    &lt;data&gt;
    262        &lt;variable name="user" type="com.example.User"/&gt;
    263    &lt;/data&gt;
    264    &lt;LinearLayout
    265        android:orientation="vertical"
    266        android:layout_width="match_parent"
    267        android:layout_height="match_parent"&gt;
    268        &lt;TextView android:layout_width="wrap_content"
    269            android:layout_height="wrap_content"
    270            android:text="&commat;{user.firstName}"/&gt;
    271        &lt;TextView android:layout_width="wrap_content"
    272            android:layout_height="wrap_content"
    273            android:text="&commat;{user.lastName}"/&gt;
    274    &lt;/LinearLayout&gt;
    275 &lt;/layout&gt;
    276 </pre>
    277 <p>
    278   The user <strong>variable</strong> within <strong>data</strong> describes a
    279   property that may be used within this layout.
    280 </p>
    281 
    282 <pre>
    283 &lt;<strong>variable name="user" type="com.example.User"</strong>/&gt;
    284 </pre>
    285 <p>
    286   Expressions within the layout are written in the attribute properties using
    287   the <code>&commat;{}</code> syntax. Here, the TextViews text is set to the
    288   firstName property of user:
    289 </p>
    290 
    291 <pre>
    292 &lt;TextView android:layout_width="wrap_content"
    293           android:layout_height="wrap_content"
    294           android:text="&commat;{user.firstName}"/&gt;
    295 </pre>
    296 <h3 id="data_object">
    297   Data Object
    298 </h3>
    299 
    300 <p>
    301   Lets assume for now that you have a plain-old Java object (POJO) for User:
    302 </p>
    303 
    304 <pre>
    305 public class User {
    306    public final String firstName;
    307    public final String lastName;
    308    public User(String firstName, String lastName) {
    309        this.firstName = firstName;
    310        this.lastName = lastName;
    311    }
    312 }
    313 </pre>
    314 <p>
    315   This type of object has data that never changes. It is common in applications
    316   to have data that is read once and never changes thereafter. It is also
    317   possible to use a JavaBeans objects:
    318 </p>
    319 
    320 <pre>
    321 public class User {
    322    private final String firstName;
    323    private final String lastName;
    324    public User(String firstName, String lastName) {
    325        this.firstName = firstName;
    326        this.lastName = lastName;
    327    }
    328    public String getFirstName() {
    329        return this.firstName;
    330    }
    331    public String getLastName() {
    332        return this.lastName;
    333    }
    334 }
    335 </pre>
    336 <p>
    337   From the perspective of data binding, these two classes are equivalent. The
    338   expression <strong><code>&commat;{user.firstName}</code></strong> used for
    339   the TextViews <strong><code>android:text</code></strong> attribute will
    340   access the <strong><code>firstName</code></strong> field in the former class
    341   and the <code>getFirstName()</code> method in the latter class. Alternatively, it
    342   will also be resolved to <code>firstName()</code> if that method exists.
    343 </p>
    344 
    345 <h3 id="binding_data">
    346   Binding Data
    347 </h3>
    348 
    349 <p>
    350   By default, a Binding class will be generated based on the name of the layout
    351   file, converting it to Pascal case and suffixing Binding to it. The above
    352   layout file was <code>main_activity.xml</code> so the generate class was
    353   <code>MainActivityBinding</code>. This class holds all the bindings from the
    354   layout properties (e.g. the <code>user</code> variable) to the layouts Views
    355   and knows how to assign values for the binding expressions.The easiest means
    356   for creating the bindings is to do it while inflating:
    357 </p>
    358 
    359 <pre>
    360 &commat;Override
    361 protected void onCreate(Bundle savedInstanceState) {
    362    super.onCreate(savedInstanceState);
    363    MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
    364    User user = new User("Test", "User");
    365    binding.setUser(user);
    366 }
    367 </pre>
    368 <p>
    369   Youre done! Run the application and youll see Test User in the UI.
    370   Alternatively, you can get the view via:
    371 </p>
    372 
    373 <pre>
    374 MainActivityBinding binding = MainActivityBinding.<em>inflate</em>(getLayoutInflater());
    375 </pre>
    376 <p>
    377   If you are using data binding items inside a ListView or RecyclerView
    378   adapter, you may prefer to use:
    379 </p>
    380 
    381 <pre>
    382 ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
    383 //or
    384 ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.layout.<em><strong>list_item</strong></em>, viewGroup, <strong>false</strong>);
    385 </pre>
    386 
    387 <h3 id="binding_events">
    388   Binding Events
    389 </h3>
    390 <p>
    391   Events may be bound to handler methods directly, similar to the way
    392   <strong><code>android:onClick</code></strong> can be assigned to a method in the Activity.
    393   Event attribute names are governed by the name of the listener method with a few exceptions.
    394   For example, {@link android.view.View.OnLongClickListener} has a method {@link android.view.View.OnLongClickListener#onLongClick onLongClick()},
    395   so the attribute for this event is <code>android:onLongClick</code>.
    396 </p>
    397 <p>
    398   To assign an event to its handler, use a normal binding expression, with the value
    399   being the method name to call. For example, if your data object has two methods:
    400 </p>
    401 <pre>public class MyHandlers {
    402     public void onClickFriend(View view) { ... }
    403     public void onClickEnemy(View view) { ... }
    404 }
    405 </pre>
    406 <p>
    407   The binding expression can assign the click listener for a View:
    408 </p>
    409 <pre>
    410 &lt;?xml version="1.0" encoding="utf-8"?&gt;
    411 &lt;layout xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    412    &lt;data&gt;
    413        &lt;variable name="handlers" type="com.example.Handlers"/&gt;
    414        &lt;variable name="user" type="com.example.User"/&gt;
    415    &lt;/data&gt;
    416    &lt;LinearLayout
    417        android:orientation="vertical"
    418        android:layout_width="match_parent"
    419        android:layout_height="match_parent"&gt;
    420        &lt;TextView android:layout_width="wrap_content"
    421            android:layout_height="wrap_content"
    422            android:text="&commat;{user.firstName}"
    423            android:onClick="&commat;{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/&gt;
    424        &lt;TextView android:layout_width="wrap_content"
    425            android:layout_height="wrap_content"
    426            android:text="&commat;{user.lastName}"
    427            android:onClick="&commat;{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/&gt;
    428    &lt;/LinearLayout&gt;
    429 &lt;/layout&gt;
    430 </pre>
    431 <h2 id="layout_details">
    432   Layout Details
    433 </h2>
    434 
    435 <h3 id="imports">
    436   Imports
    437 </h3>
    438 
    439 <p>
    440   Zero or more <strong><code>import</code></strong> elements may be used inside
    441   the <strong><code>data</code></strong> element. These allow easy reference to
    442   classes inside your layout file, just like in Java.
    443 </p>
    444 
    445 <pre>
    446 &lt;data&gt;
    447     &lt;import type="android.view.View"/&gt;
    448 &lt;/data&gt;
    449 </pre>
    450 <p>
    451   Now, View may be used within your binding expression:
    452 </p>
    453 
    454 <pre>
    455 &lt;TextView
    456    android:text="&commat;{user.lastName}"
    457    android:layout_width="wrap_content"
    458    android:layout_height="wrap_content"
    459    android:visibility="&commat;{user.isAdult ? View.VISIBLE : View.GONE}"/&gt;
    460 </pre>
    461 <p>
    462   When there are class name conflicts, one of the classes may be renamed to an
    463   alias:
    464 </p>
    465 
    466 <pre>
    467 &lt;import type="android.view.View"/&gt;
    468 &lt;import type="com.example.real.estate.View"
    469         alias="Vista"/&gt;
    470 </pre>
    471 <p>
    472   Now, <strong><code>Vista</code></strong> may be used to reference the
    473   <code>com.example.real.estate.View</code> and
    474   <strong><code>View</code></strong> may be used to reference
    475   <code>android.view.View</code> within the layout file. Imported types may be
    476   used as type references in variables and expressions:
    477 </p>
    478 
    479 <pre>
    480 &lt;data&gt;
    481     &lt;import type="com.example.User"/&gt;
    482     &lt;import type="java.util.List"/&gt;
    483     &lt;variable name="user" type="User"/&gt;
    484     &lt;variable name="userList" type="List&amp;lt;User&gt;"/&gt;
    485 &lt;/data&gt;
    486 </pre>
    487 <p class="caution">
    488   <strong>Note</strong>: Android Studio does not yet handle imports so the
    489   autocomplete for imported variables may not work in your IDE. Your
    490   application will still compile fine and you can work around the IDE issue by
    491   using fully qualified names in your variable definitions.
    492 </p>
    493 
    494 <pre>
    495 &lt;TextView
    496    android:text="&commat;{((User)(user.connection)).lastName}"
    497    android:layout_width="wrap_content"
    498    android:layout_height="wrap_content"/&gt;
    499 </pre>
    500 <p>
    501   Imported types may also be used when referencing static fields and methods in
    502   expressions:
    503 </p>
    504 
    505 <pre>
    506 &lt;data&gt;
    507     &lt;import type="com.example.MyStringUtils"/&gt;
    508     &lt;variable name="user" type="com.example.User"/&gt;
    509 &lt;/data&gt;
    510 
    511 &lt;TextView
    512    android:text="&commat;{MyStringUtils.capitalize(user.lastName)}"
    513    android:layout_width="wrap_content"
    514    android:layout_height="wrap_content"/&gt;
    515 </pre>
    516 <p>
    517   Just as in Java, <code>java.lang.*</code> is imported automatically.
    518 </p>
    519 
    520 <h3 id="variables">
    521   Variables
    522 </h3>
    523 
    524 <p>
    525   Any number of <strong><code>variable</code></strong> elements may be used
    526   inside the <strong><code>data</code></strong> element. Each
    527   <strong><code>variable</code></strong> element describes a property that may
    528   be set on the layout to be used in binding expressions within the layout
    529   file.
    530 </p>
    531 
    532 <pre>
    533 &lt;data&gt;
    534     &lt;import type="android.graphics.drawable.Drawable"/&gt;
    535     &lt;variable name="user"  type="com.example.User"/&gt;
    536     &lt;variable name="image" type="Drawable"/&gt;
    537     &lt;variable name="note"  type="String"/&gt;
    538 &lt;/data&gt;
    539 </pre>
    540 <p>
    541   The variable types are inspected at compile time, so if a variable implements
    542   {@link android.databinding.Observable} or is an <a href=
    543   "#observable_collections">observable collection</a>, that should be reflected
    544   in the type. If the variable is a base class or interface that does not
    545   implement the Observable* interface, the variables will <strong>not
    546   be</strong> observed!
    547 </p>
    548 
    549 <p>
    550   When there are different layout files for various configurations (e.g.
    551   landscape or portrait), the variables will be combined. There must not be
    552   conflicting variable definitions between these layout files.
    553 </p>
    554 
    555 <p>
    556   The generated binding class will have a setter and getter for each of the
    557   described variables. The variables will take the default Java values until
    558   the setter is called &mdash; <code>null</code> for reference types,
    559   <code>0</code> for <code>int</code>, <code>false</code> for
    560   <code>boolean</code>, etc.
    561 </p>
    562 
    563 <h3 id="custom_binding_class_names">
    564   Custom Binding Class Names
    565 </h3>
    566 
    567 <p>
    568   By default, a Binding class is generated based on the name of the layout
    569   file, starting it with upper-case, removing underscores ( _ ) and
    570   capitalizing the following letter and then suffixing Binding. This class
    571   will be placed in a databinding package under the module package. For
    572   example, the layout file <code>contact_item.xml</code> will generate
    573   <code>ContactItemBinding</code>. If the module package is
    574   <code>com.example.my.app</code>, then it will be placed in
    575   <code>com.example.my.app.databinding</code>.
    576 </p>
    577 
    578 <p>
    579   Binding classes may be renamed or placed in different packages by adjusting
    580   the <strong><code>class</code></strong> attribute of the
    581   <strong><code>data</code></strong> element. For example:
    582 </p>
    583 
    584 <pre>
    585 &lt;data class="ContactItem"&gt;
    586     ...
    587 &lt;/data&gt;
    588 </pre>
    589 <p>
    590   This generates the binding class as <code>ContactItem</code> in the
    591   databinding package in the module package. If the class should be generated
    592   in a different package within the module package, it may be prefixed with
    593   .:
    594 </p>
    595 
    596 <pre>
    597 &lt;data class=".ContactItem"&gt;
    598     ...
    599 &lt;/data&gt;
    600 </pre>
    601 <p>
    602   In this case, <code>ContactItem</code> is generated in the module package
    603   directly. Any package may be used if the full package is provided:
    604 </p>
    605 
    606 <pre>
    607 &lt;data class="com.example.ContactItem"&gt;
    608     ...
    609 &lt;/data&gt;
    610 </pre>
    611 <h3 id="includes">
    612   Includes
    613 </h3>
    614 
    615 <p>
    616   Variables may be passed into an included layout&apos;s binding from the
    617   containing layout by using the application namespace and the variable name in
    618   an attribute:
    619 </p>
    620 
    621 <pre>
    622 &lt;?xml version="1.0" encoding="utf-8"?&gt;
    623 &lt;layout xmlns:android="http://schemas.android.com/apk/res/android"
    624         xmlns:bind="http://schemas.android.com/apk/res-auto"&gt;
    625    &lt;data&gt;
    626        &lt;variable name="user" type="com.example.User"/&gt;
    627    &lt;/data&gt;
    628    &lt;LinearLayout
    629        android:orientation="vertical"
    630        android:layout_width="match_parent"
    631        android:layout_height="match_parent"&gt;
    632        &lt;include layout="&commat;layout/name"
    633            bind:user="&commat;{user}"/&gt;
    634        &lt;include layout="&commat;layout/contact"
    635            bind:user="&commat;{user}"/&gt;
    636    &lt;/LinearLayout&gt;
    637 &lt;/layout&gt;
    638 </pre>
    639 <p>
    640   Here, there must be a <code>user</code> variable in both the
    641   <code>name.xml</code> and <code>contact.xml</code> layout files.
    642 </p>
    643 <p>
    644   Data binding does not support include as a direct child of a merge element. For example,
    645   <strong>the following layout is not supported:</strong>
    646 </p>
    647 <pre>
    648 &lt;?xml version="1.0" encoding="utf-8"?&gt;
    649 &lt;layout xmlns:android="http://schemas.android.com/apk/res/android"
    650         xmlns:bind="http://schemas.android.com/apk/res-auto"&gt;
    651    &lt;data&gt;
    652        &lt;variable name="user" type="com.example.User"/&gt;
    653    &lt;/data&gt;
    654    &lt;merge&gt;
    655        &lt;include layout="&commat;layout/name"
    656            bind:user="&commat;{user}"/&gt;
    657        &lt;include layout="&commat;layout/contact"
    658            bind:user="&commat;{user}"/&gt;
    659    &lt;/merge&gt;
    660 &lt;/layout&gt;
    661 </pre>
    662 <h3 id="expression_language">
    663   Expression Language
    664 </h3>
    665 
    666 <h4 id="common_features">
    667   Common Features
    668 </h4>
    669 
    670 <p>
    671   The expression language looks a lot like a Java expression. These are the
    672   same:
    673 </p>
    674 
    675 <ul>
    676   <li>Mathematical <strong><code>+ - / * %</code></strong>
    677   </li>
    678 
    679   <li>String concatenation <strong><code>+</code></strong>
    680   </li>
    681 
    682   <li>
    683     Logical <strong><code>&& ||</code></strong>
    684   </li>
    685 
    686   <li>Binary <strong><code>& | ^</code></strong>
    687   </li>
    688 
    689   <li>Unary <strong><code>+ - ! ~</code></strong>
    690   </li>
    691 
    692   <li>Shift <strong><code>&gt;&gt; &gt;&gt;&gt; &lt;&lt;</code></strong>
    693   </li>
    694 
    695   <li>Comparison <strong><code>== &gt; &lt; &gt;= &lt;=</code></strong>
    696   </li>
    697 
    698   <li>
    699     <strong><code>instanceof</code></strong>
    700   </li>
    701 
    702   <li>Grouping <strong><code>()</code></strong>
    703   </li>
    704 
    705   <li>Literals - character, String, numeric, <strong><code>null</code></strong>
    706   </li>
    707 
    708   <li>Cast
    709   </li>
    710 
    711   <li>Method calls
    712   </li>
    713 
    714   <li>Field access
    715   </li>
    716 
    717   <li>Array access <strong><code>[]</code></strong>
    718   </li>
    719 
    720   <li>Ternary operator <strong><code>?:</code></strong>
    721   </li>
    722 </ul>
    723 
    724 <p>
    725   Examples:
    726 </p>
    727 
    728 <pre>
    729 android:text="&commat;{String.valueOf(index + 1)}"
    730 android:visibility="&commat;{age &amp;lt; 13 ? View.GONE : View.VISIBLE}"
    731 android:transitionName=&apos;&commat;{"image_" + id}&apos;
    732 </pre>
    733 <h4 id="missing_operations">
    734   Missing Operations
    735 </h4>
    736 
    737 <p>
    738   A few operations are missing from the expression syntax that you can use in
    739   Java.
    740 </p>
    741 
    742 <ul>
    743   <li>
    744     <strong><code>this</code></strong>
    745   </li>
    746 
    747   <li>
    748     <strong><code>super</code></strong>
    749   </li>
    750 
    751   <li>
    752     <strong><code>new</code></strong>
    753   </li>
    754 
    755   <li>Explicit generic invocation
    756   </li>
    757 </ul>
    758 
    759 <h4 id="null_coalescing_operator">
    760   Null Coalescing Operator
    761 </h4>
    762 
    763 <p>
    764   The null coalescing operator (<strong><code>??</code></strong>) chooses the
    765   left operand if it is not null or the right if it is null.
    766 </p>
    767 
    768 <pre>
    769 <strong>android:text="&commat;{user.displayName ?? user.lastName}"</strong>
    770 </pre>
    771 <p>
    772   This is functionally equivalent to:
    773 </p>
    774 
    775 <pre>
    776 <strong>android:text="&commat;{user.displayName != null ? user.displayName : user.lastName}"</strong>
    777 </pre>
    778 <h4 id="property_reference">
    779   Property Reference
    780 </h4>
    781 
    782 <p>
    783   The first was already discussed in the <a href=
    784   "#writing_your_first_data_binding_expressions">Writing your first data
    785   binding expressions</a> above: short form JavaBean references. When an
    786   expression references a property on a class, it uses the same format for
    787   fields, getters, and ObservableFields.
    788 </p>
    789 
    790 <pre>
    791 <strong>android:text="&commat;{user.lastName}"</strong>
    792 </pre>
    793 <h4>
    794   Avoiding NullPointerException
    795 </h4>
    796 
    797 <p>
    798   Generated data binding code automatically checks for nulls and avoid null
    799   pointer exceptions. For example, in the expression
    800   <code>&commat;{user.name}</code>, if <code>user</code> is null,
    801   <code>user.name</code> will be assigned its default value (null). If you were
    802   referencing <code>user.age</code>, where age is an <code>int</code>, then it
    803   would default to 0.
    804 </p>
    805 
    806 <h4 id="collections">
    807   Collections
    808 </h4>
    809 
    810 <p>
    811   Common collections: arrays, lists, sparse lists, and maps, may be accessed
    812   using the <code>[]</code> operator for convenience.
    813 </p>
    814 
    815 <pre>
    816 &lt;data&gt;
    817     &lt;import type="android.util.SparseArray"/&gt;
    818     &lt;import type="java.util.Map"/&gt;
    819     &lt;import type="java.util.List"/&gt;
    820     &lt;variable name="list" type="List&amp;lt;String&gt;"/&gt;
    821     &lt;variable name="sparse" type="SparseArray&amp;lt;String&gt;"/&gt;
    822     &lt;variable name="map" type="Map&amp;lt;String, String&gt;"/&gt;
    823     &lt;variable name="index" type="int"/&gt;
    824     &lt;variable name="key" type="String"/&gt;
    825 &lt;/data&gt;
    826 
    827 android:text="&commat;{list[index]}"
    828 
    829 android:text="&commat;{sparse[index]}"
    830 
    831 android:text="&commat;{map[key]}"
    832 
    833 </pre>
    834 <h4 id="string_literals">
    835   String Literals
    836 </h4>
    837 
    838 <p>
    839   When using single quotes around the attribute value, it is easy to use double
    840   quotes in the expression:
    841 </p>
    842 
    843 <pre>
    844 android:text=&apos;&commat;{map["firstName"]}&apos;
    845 </pre>
    846 <p>
    847   It is also possible to use double quotes to surround the attribute value.
    848   When doing so, String literals should either use the &amp;quot; or back quote
    849   (`).
    850 </p>
    851 
    852 <pre>
    853 android:text="&commat;{map[`firstName`}"
    854 android:text="&commat;{map[&amp;quot;firstName&amp;quot;]}"
    855 </pre>
    856 <h4 id="resources">
    857   Resources
    858 </h4>
    859 
    860 <p>
    861   It is possible to access resources as part of expressions using the normal
    862   syntax:
    863 </p>
    864 
    865 <pre>
    866 android:padding="&commat;{large? &commat;dimen/largePadding : &commat;dimen/smallPadding}"
    867 </pre>
    868 <p>
    869   Format strings and plurals may be evaluated by providing parameters:
    870 </p>
    871 
    872 <pre>
    873 android:text="&commat;{&commat;string/nameFormat(firstName, lastName)}"
    874 android:text="&commat;{&commat;plurals/banana(bananaCount)}"
    875 </pre>
    876 <p>
    877   When a plural takes multiple parameters, all parameters should be passed:
    878 </p>
    879 
    880 <pre>
    881 
    882   Have an orange
    883   Have %d oranges
    884 
    885 android:text="&commat;{&commat;plurals/orange(orangeCount, orangeCount)}"
    886 </pre>
    887 <p>
    888   Some resources require explicit type evaluation.
    889 </p>
    890 
    891 <table>
    892   <tr>
    893     <th>
    894       Type
    895     </th>
    896     <th>
    897       Normal Reference
    898     </th>
    899     <th>
    900       Expression Reference
    901     </th>
    902   </tr>
    903 
    904   <tr>
    905     <td>
    906       String[]
    907     </td>
    908     <td>
    909       &commat;array
    910     </td>
    911     <td>
    912       &commat;stringArray
    913     </td>
    914   </tr>
    915 
    916   <tr>
    917     <td>
    918       int[]
    919     </td>
    920     <td>
    921       &commat;array
    922     </td>
    923     <td>
    924       &commat;intArray
    925     </td>
    926   </tr>
    927 
    928   <tr>
    929     <td>
    930       TypedArray
    931     </td>
    932     <td>
    933       &commat;array
    934     </td>
    935     <td>
    936       &commat;typedArray
    937     </td>
    938   </tr>
    939 
    940   <tr>
    941     <td>
    942       Animator
    943     </td>
    944     <td>
    945       &commat;animator
    946     </td>
    947     <td>
    948       &commat;animator
    949     </td>
    950   </tr>
    951 
    952   <tr>
    953     <td>
    954       StateListAnimator
    955     </td>
    956     <td>
    957       &commat;animator
    958     </td>
    959     <td>
    960       &commat;stateListAnimator
    961     </td>
    962   </tr>
    963 
    964   <tr>
    965     <td>
    966       color <code>int</code>
    967     </td>
    968     <td>
    969       &commat;color
    970     </td>
    971     <td>
    972       &commat;color
    973     </td>
    974   </tr>
    975 
    976   <tr>
    977     <td>
    978       ColorStateList
    979     </td>
    980     <td>
    981       &commat;color
    982     </td>
    983     <td>
    984       &commat;colorStateList
    985     </td>
    986   </tr>
    987 </table>
    988 
    989 <h2 id="data_objects">
    990   Data Objects
    991 </h2>
    992 
    993 <p>
    994   Any plain old Java object (POJO) may be used for data binding, but modifying
    995   a POJO will not cause the UI to update. The real power of data binding can be
    996   used by giving your data objects the ability to notify when data changes.
    997   There are three different data change notification mechanisms,
    998   <a href="#observable_objects">Observable objects</a>,
    999   <a href="#observablefields">observable fields</a>, and
   1000   <a href="#observable_collections">observable collection</a>s.
   1001 </p>
   1002 
   1003 <p>
   1004   When one of these observable data object is bound to the UI and a property of
   1005   the data object changes, the UI will be updated automatically.
   1006 </p>
   1007 
   1008 <h3 id="observable_objects">
   1009   Observable Objects
   1010 </h3>
   1011 
   1012 <p>
   1013   A class implementing the {@link android.databinding.Observable} interface
   1014   will allow the binding to attach a single listener to a bound object to
   1015   listen for changes of all properties on that object.
   1016 </p>
   1017 
   1018 <p>
   1019   The {@link android.databinding.Observable} interface has a mechanism to add and remove
   1020   listeners, but notifying is up to the developer. To make development easier,
   1021   a base class, {@link android.databinding.BaseObservable}, was created to implement the
   1022   listener registration mechanism. The data class implementer is still
   1023   responsible for notifying when the properties change. This is done by
   1024   assigning a {@link android.databinding.Bindable} annotation to the getter and notifying in
   1025   the setter.
   1026 </p>
   1027 
   1028 <pre>
   1029 private static class User extends BaseObservable {
   1030    private String firstName;
   1031    private String lastName;
   1032    &commat;Bindable
   1033    public String getFirstName() {
   1034        return this.firstName;
   1035    }
   1036    &commat;Bindable
   1037    public String getLastName() {
   1038        return this.lastName;
   1039    }
   1040    public void setFirstName(String firstName) {
   1041        this.firstName = firstName;
   1042        notifyPropertyChanged(BR.firstName);
   1043    }
   1044    public void setLastName(String lastName) {
   1045        this.lastName = lastName;
   1046        notifyPropertyChanged(BR.lastName);
   1047    }
   1048 }
   1049 </pre>
   1050 <p>
   1051   The {@link android.databinding.Bindable} annotation generates an entry in the BR class file
   1052   during compilation. The BR class file will be generated in the module
   1053   package. If the base class for data classes cannot be changed, the
   1054   {@link android.databinding.Observable} interface may be implemented using the convenient
   1055   {@link android.databinding.PropertyChangeRegistry} to store and notify listeners
   1056   efficiently.
   1057 </p>
   1058 
   1059 <h3 id="observablefields">
   1060   ObservableFields
   1061 </h3>
   1062 
   1063 <p>
   1064   A little work is involved in creating {@link android.databinding.Observable} classes, so
   1065   developers who want to save time or have few properties may use
   1066   {@link android.databinding.ObservableField} and its siblings
   1067   {@link android.databinding.ObservableBoolean},
   1068   {@link android.databinding.ObservableByte},
   1069   {@link android.databinding.ObservableChar},
   1070   {@link android.databinding.ObservableShort},
   1071   {@link android.databinding.ObservableInt},
   1072   {@link android.databinding.ObservableLong},
   1073   {@link android.databinding.ObservableFloat},
   1074   {@link android.databinding.ObservableDouble}, and
   1075   {@link android.databinding.ObservableParcelable}.
   1076   <code>ObservableFields</code> are self-contained observable objects that have a single
   1077   field. The primitive versions avoid boxing and unboxing during access operations.
   1078   To use, create a public final field in the data class:
   1079 </p>
   1080 
   1081 <pre>
   1082 private static class User {
   1083    public final ObservableField&lt;String&gt; firstName =
   1084        new ObservableField&lt;&gt;();
   1085    public final ObservableField&lt;String&gt; lastName =
   1086        new ObservableField&lt;&gt;();
   1087    public final ObservableInt age = new ObservableInt();
   1088 }
   1089 </pre>
   1090 <p>
   1091   That&apos;s it! To access the value, use the set and get accessor methods:
   1092 </p>
   1093 
   1094 <pre>
   1095 user.firstName.set("Google");
   1096 int age = user.age.get();
   1097 </pre>
   1098 <h3 id="observable_collections">
   1099   Observable Collections
   1100 </h3>
   1101 
   1102 <p>
   1103   Some applications use more dynamic structures to hold data. Observable
   1104   collections allow keyed access to these data objects.
   1105   {@link android.databinding.ObservableArrayMap} is
   1106   useful when the key is a reference type, such as String.
   1107 </p>
   1108 
   1109 <pre>
   1110 ObservableArrayMap&lt;String, Object&gt; user = new ObservableArrayMap&lt;&gt;();
   1111 user.put("firstName", "Google");
   1112 user.put("lastName", "Inc.");
   1113 user.put("age", 17);
   1114 </pre>
   1115 <p>
   1116   In the layout, the map may be accessed through the String keys:
   1117 </p>
   1118 
   1119 <pre>
   1120 &lt;data&gt;
   1121     &lt;import type="android.databinding.ObservableMap"/&gt;
   1122     &lt;variable name="user" type="ObservableMap&amp;lt;String, Object&gt;"/&gt;
   1123 &lt;/data&gt;
   1124 
   1125 &lt;TextView
   1126    android:text=&apos;&commat;{user["lastName"]}&apos;
   1127    android:layout_width="wrap_content"
   1128    android:layout_height="wrap_content"/&gt;
   1129 &lt;TextView
   1130    android:text=&apos;&commat;{String.valueOf(1 + (Integer)user["age"])}&apos;
   1131    android:layout_width="wrap_content"
   1132    android:layout_height="wrap_content"/&gt;
   1133 </pre>
   1134 <p>
   1135   {@link android.databinding.ObservableArrayList} is useful when the key is an integer:
   1136 </p>
   1137 
   1138 <pre>
   1139 ObservableArrayList&lt;Object&gt; user = new ObservableArrayList&lt;&gt;();
   1140 user.add("Google");
   1141 user.add("Inc.");
   1142 user.add(17);
   1143 </pre>
   1144 <p>
   1145   In the layout, the list may be accessed through the indices:
   1146 </p>
   1147 
   1148 <pre>
   1149 &lt;data&gt;
   1150     &lt;import type="android.databinding.ObservableList"/&gt;
   1151     &lt;import type="com.example.my.app.Fields"/&gt;
   1152     &lt;variable name="user" type="ObservableList&amp;lt;Object&gt;"/&gt;
   1153 &lt;/data&gt;
   1154 
   1155 &lt;TextView
   1156    android:text=&apos;&commat;{user[Fields.LAST_NAME]}&apos;
   1157    android:layout_width="wrap_content"
   1158    android:layout_height="wrap_content"/&gt;
   1159 &lt;TextView
   1160    android:text=&apos;&commat;{String.valueOf(1 + (Integer)user[Fields.AGE])}&apos;
   1161    android:layout_width="wrap_content"
   1162    android:layout_height="wrap_content"/&gt;
   1163 </pre>
   1164 <h2 id="generated_binding">
   1165   Generated Binding
   1166 </h2>
   1167 
   1168 <p>
   1169   The generated binding class links the layout variables with the Views within
   1170   the layout. As discussed earlier, the name and package of the Binding may be
   1171   <a href="#custom_binding_class_names">customized</a>. The Generated binding
   1172   classes all extend {@link android.databinding.ViewDataBinding}.
   1173 </p>
   1174 
   1175 <h3 id="creating">
   1176   Creating
   1177 </h3>
   1178 
   1179 <p>
   1180   The binding should be created soon after inflation to ensure that the View
   1181   hierarchy is not disturbed prior to binding to the Views with expressions
   1182   within the layout. There are a few ways to bind to a layout. The most common
   1183   is to use the static methods on the Binding class.The inflate method inflates
   1184   the View hierarchy and binds to it all it one step. There is a simpler
   1185   version that only takes a {@link android.view.LayoutInflater} and one that takes a
   1186   {@link android.view.ViewGroup} as well:
   1187 </p>
   1188 
   1189 <pre>
   1190 MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater);
   1191 MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater, viewGroup, false);
   1192 </pre>
   1193 <p>
   1194   If the layout was inflated using a different mechanism, it may be bound
   1195   separately:
   1196 </p>
   1197 
   1198 <pre>
   1199 MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
   1200 </pre>
   1201 <p>
   1202   Sometimes the binding cannot be known in advance. In such cases, the binding
   1203   can be created using the {@link android.databinding.DataBindingUtil} class:
   1204 </p>
   1205 
   1206 <pre>
   1207 ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId,
   1208     parent, attachToParent);
   1209 ViewDataBinding binding = DataBindingUtil.bindTo(viewRoot, layoutId);
   1210 </pre>
   1211 <h3 id="views_with_ids">
   1212   Views With IDs
   1213 </h3>
   1214 
   1215 <p>
   1216   A public final field will be generated for each View with an ID in the
   1217   layout. The binding does a single pass on the View hierarchy, extracting the
   1218   Views with IDs. This mechanism can be faster than calling findViewById for
   1219   several Views. For example:
   1220 </p>
   1221 
   1222 <pre>
   1223 &lt;layout xmlns:android="http://schemas.android.com/apk/res/android"&gt;
   1224    &lt;data&gt;
   1225        &lt;variable name="user" type="com.example.User"/&gt;
   1226    &lt;/data&gt;
   1227    &lt;LinearLayout
   1228        android:orientation="vertical"
   1229        android:layout_width="match_parent"
   1230        android:layout_height="match_parent"&gt;
   1231        &lt;TextView android:layout_width="wrap_content"
   1232            android:layout_height="wrap_content"
   1233            android:text="&commat;{user.firstName}"
   1234    android:id="&commat;+id/firstName"/&gt;
   1235        &lt;TextView android:layout_width="wrap_content"
   1236            android:layout_height="wrap_content"
   1237            android:text="&commat;{user.lastName}"
   1238   android:id="&commat;+id/lastName"/&gt;
   1239    &lt;/LinearLayout&gt;
   1240 &lt;/layout&gt;
   1241 </pre>
   1242 <p>
   1243   Will generate a binding class with:
   1244 </p>
   1245 
   1246 <pre>
   1247 public final TextView firstName;
   1248 public final TextView lastName;
   1249 </pre>
   1250 <p>
   1251   IDs are not nearly as necessary as without data binding, but there are still
   1252   some instances where access to Views are still necessary from code.
   1253 </p>
   1254 
   1255 <h3 id="variables2">
   1256   Variables
   1257 </h3>
   1258 
   1259 <p>
   1260   Each variable will be given accessor methods.
   1261 </p>
   1262 
   1263 <pre>
   1264 &lt;data&gt;
   1265     &lt;import type="android.graphics.drawable.Drawable"/&gt;
   1266     &lt;variable name="user"  type="com.example.User"/&gt;
   1267     &lt;variable name="image" type="Drawable"/&gt;
   1268     &lt;variable name="note"  type="String"/&gt;
   1269 &lt;/data&gt;
   1270 </pre>
   1271 <p>
   1272   will generate setters and getters in the binding:
   1273 </p>
   1274 
   1275 <pre>
   1276 public abstract com.example.User getUser();
   1277 public abstract void setUser(com.example.User user);
   1278 public abstract Drawable getImage();
   1279 public abstract void setImage(Drawable image);
   1280 public abstract String getNote();
   1281 public abstract void setNote(String note);
   1282 </pre>
   1283 <h3 id="viewstubs">
   1284   ViewStubs
   1285 </h3>
   1286 
   1287 <p>
   1288   {@link android.view.ViewStub}s are a little different from normal Views. They start off invisible
   1289   and when they either are made visible or are explicitly told to inflate, they
   1290   replace themselves in the layout by inflating another layout.
   1291 </p>
   1292 
   1293 <p>
   1294   Because the <code>ViewStub</code> essentially disappears from the View hierarchy, the View
   1295   in the binding object must also disappear to allow collection. Because the
   1296   Views are final, a {@link android.databinding.ViewStubProxy} object takes the place of the
   1297   <code>ViewStub</code>, giving the developer access to the ViewStub when it exists and also
   1298   access to the inflated View hierarchy when the <code>ViewStub</code> has been inflated.
   1299 </p>
   1300 
   1301 <p>
   1302   When inflating another layout, a binding must be established for the new
   1303   layout. Therefore, the <code>ViewStubProxy</code> must listen to the <code>ViewStub</code>&apos;s
   1304   {@link android.view.ViewStub.OnInflateListener} and establish the binding at that time. Since
   1305   only one can exist, the <code>ViewStubProxy</code> allows the developer to set an
   1306   <code>OnInflateListener</code> on it that it will call after establishing the binding.
   1307 </p>
   1308 
   1309 <h3 id="advanced_binding">
   1310   Advanced Binding
   1311 </h3>
   1312 
   1313 <h4 id="dynamic_variables">
   1314   Dynamic Variables
   1315 </h4>
   1316 
   1317 <p>
   1318   At times, the specific binding class won&apos;t be known. For example, a
   1319   {@link android.support.v7.widget.RecyclerView.Adapter} operating against arbitrary layouts
   1320   won&apos;t know the specific binding class. It still must assign the binding value during the
   1321   {@link android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder}.
   1322 </p>
   1323 
   1324 <p>
   1325   In this example, all layouts that the RecyclerView binds to have an "item"
   1326   variable. The <code>BindingHolder</code> has a <code>getBinding</code> method returning the
   1327   {@link android.databinding.ViewDataBinding} base.
   1328 </p>
   1329 
   1330 <pre>
   1331 public void onBindViewHolder(BindingHolder holder, int position) {
   1332    final T item = mItems.get(position);
   1333    holder.getBinding().setVariable(BR.item, item);
   1334    holder.getBinding().executePendingBindings();
   1335 }
   1336 </pre>
   1337 <h4 id="immediate_binding">
   1338   Immediate Binding
   1339 </h4>
   1340 
   1341 <p>
   1342   When a variable or observable changes, the binding will be scheduled to
   1343   change before the next frame. There are times, however, when binding must be
   1344   executed immediately. To force execution, use the
   1345   {@link android.databinding.ViewDataBinding#executePendingBindings()} method.
   1346 </p>
   1347 
   1348 <h4>
   1349   Background Thread
   1350 </h4>
   1351 
   1352 <p>
   1353   You can change your data model in a background thread as long as it is not a
   1354   collection. Data binding will localize each variable / field while evaluating
   1355   to avoid any concurrency issues.
   1356 </p>
   1357 
   1358 <h2 id="attribute_setters">
   1359   Attribute Setters
   1360 </h2>
   1361 
   1362 <p>
   1363   Whenever a bound value changes, the generated binding class must call a
   1364   setter method on the View with the binding expression. The data binding
   1365   framework has ways to customize which method to call to set the value.
   1366 </p>
   1367 
   1368 <h3 id="automatic_setters">
   1369   Automatic Setters
   1370 </h3>
   1371 For an attribute, data binding tries to find the method setAttribute. The
   1372 namespace for the attribute does not matter, only the attribute name itself.
   1373 <p>
   1374   For example, an expression associated with TextView&apos;s attribute
   1375   <strong><code>android:text</code></strong> will look for a setText(String).
   1376   If the expression returns an int, data binding will search for a setText(int)
   1377   method. Be careful to have the expression return the correct type, casting if
   1378   necessary. Note that data binding will work even if no attribute exists with
   1379   the given name. You can then easily "create" attributes for any setter by
   1380   using data binding. For example, support DrawerLayout doesn&apos;t have any
   1381   attributes, but plenty of setters. You can use the automatic setters to use
   1382   one of these.
   1383 </p>
   1384 
   1385 <pre>
   1386 &lt;android.support.v4.widget.<strong>DrawerLayout
   1387     android:layout_width="wrap_content"
   1388     android:layout_height="wrap_content"
   1389     app:scrimColor="&commat;{&commat;color/scrim}"
   1390     app:drawerListener="&commat;{fragment.drawerListener}"/&gt;</strong>
   1391 </pre>
   1392 <h3 id="renamed_setters">
   1393   Renamed Setters
   1394 </h3>
   1395 
   1396 <p>
   1397   Some attributes have setters that don&apos;t match by name. For these
   1398   methods, an attribute may be associated with the setter through
   1399   {@link android.databinding.BindingMethods} annotation. This must be associated with
   1400   a class and contains {@link android.databinding.BindingMethod} annotations, one for
   1401   each renamed method. For example, the <strong><code>android:tint</code></strong> attribute
   1402   is really associated with {@link android.widget.ImageView#setImageTintList}, not
   1403   <code>setTint</code>.
   1404 </p>
   1405 
   1406 <pre>
   1407 &commat;BindingMethods({
   1408        &commat;BindingMethod(type = "android.widget.ImageView",
   1409                       attribute = "android:tint",
   1410                       method = "setImageTintList"),
   1411 })
   1412 </pre>
   1413 <p>
   1414   It is unlikely that developers will need to rename setters; the android
   1415   framework attributes have already been implemented.
   1416 </p>
   1417 
   1418 <h3 id="custom_setters">
   1419   Custom Setters
   1420 </h3>
   1421 
   1422 <p>
   1423   Some attributes need custom binding logic. For example, there is no
   1424   associated setter for the <strong><code>android:paddingLeft</code></strong>
   1425   attribute. Instead, <code>setPadding(left, top, right, bottom)</code> exists.
   1426   A static binding adapter method with the {@link android.databinding.BindingAdapter}
   1427   annotation allows the developer to customize how a setter for an attribute is
   1428   called.
   1429 </p>
   1430 
   1431 <p>
   1432   The android attributes have already had <code>BindingAdapter</code>s created.
   1433   For example, here is the one for <code>paddingLeft</code>:
   1434 </p>
   1435 
   1436 <pre>
   1437 &commat;BindingAdapter("android:paddingLeft")
   1438 public static void setPaddingLeft(View view, int padding) {
   1439    view.setPadding(padding,
   1440                    view.getPaddingTop(),
   1441                    view.getPaddingRight(),
   1442                    view.getPaddingBottom());
   1443 }
   1444 </pre>
   1445 <p>
   1446   Binding adapters are useful for other types of customization. For example, a
   1447   custom loader can be called off-thread to load an image.
   1448 </p>
   1449 
   1450 <p>
   1451   Developer-created binding adapters will override the data binding default
   1452   adapters when there is a conflict.
   1453 </p>
   1454 
   1455 <p>
   1456   You can also have adapters that receive multiple parameters.
   1457 </p>
   1458 
   1459 <pre>
   1460 &commat;BindingAdapter({"bind:imageUrl", "bind:error"})
   1461 public static void loadImage(ImageView view, String url, Drawable error) {
   1462    Picasso.with(view.getContext()).load(url).error(error).into(view);
   1463 }
   1464 </pre>
   1465 <pre>
   1466 &lt;ImageView app:imageUrl=&commat;{venue.imageUrl}
   1467 app:error=&commat;{&commat;drawable/venueError}/&gt;
   1468 </pre>
   1469 
   1470 <p>
   1471   This adapter will be called if both <strong>imageUrl</strong> and
   1472   <strong>error</strong> are used for an ImageView and <em>imageUrl</em> is a
   1473   string and <em>error</em> is a drawable.
   1474 </p>
   1475 
   1476 <ul>
   1477   <li>Custom namespaces are ignored during matching.
   1478   </li>
   1479 
   1480   <li>You can also write adapters for android namespace.
   1481   </li>
   1482 </ul>
   1483 
   1484 <p>
   1485   Binding adapter methods may optionally take the old values in their handlers. A method
   1486   taking old and new values should have all old values for the attributes come first, followed
   1487   by the new values:
   1488 </p>
   1489 <pre>
   1490 &commat;BindingAdapter("android:paddingLeft")
   1491 public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
   1492    if (oldPadding != newPadding) {
   1493        view.setPadding(newPadding,
   1494                        view.getPaddingTop(),
   1495                        view.getPaddingRight(),
   1496                        view.getPaddingBottom());
   1497    }
   1498 }
   1499 </pre>
   1500 <p>
   1501   Event handlers may only be used with interfaces or abstract classes with one abstract method.
   1502   For example:
   1503 </p>
   1504 <pre>
   1505 &commat;BindingAdapter("android:onLayoutChange")
   1506 public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,
   1507        View.OnLayoutChangeListener newValue) {
   1508     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   1509         if (oldValue != null) {
   1510             view.removeOnLayoutChangeListener(oldValue);
   1511         }
   1512         if (newValue != null) {
   1513             view.addOnLayoutChangeListener(newValue);
   1514         }
   1515     }
   1516 }
   1517 </pre>
   1518 <p>
   1519   When a listener has multiple methods, it must be split into multiple listeners. For example,
   1520   {@link android.view.View.OnAttachStateChangeListener} has two methods:
   1521   {@link android.view.View.OnAttachStateChangeListener#onViewAttachedToWindow onViewAttachedToWindow()} and
   1522   {@link android.view.View.OnAttachStateChangeListener#onViewDetachedFromWindow onViewDetachedFromWindow()}.
   1523   We must then create two interfaces to differentiate the attributes and handlers for them.
   1524 </p>
   1525 
   1526 <pre>
   1527 &commat;TargetApi(VERSION_CODES.HONEYCOMB_MR1)
   1528 public interface OnViewDetachedFromWindow {
   1529     void onViewDetachedFromWindow(View v);
   1530 }
   1531 
   1532 &commat;TargetApi(VERSION_CODES.HONEYCOMB_MR1)
   1533 public interface OnViewAttachedToWindow {
   1534     void onViewAttachedToWindow(View v);
   1535 }
   1536 </pre>
   1537 <p>
   1538   Because changing one listener will also affect the other, we must have three different
   1539   binding adapters, one for each attribute and one for both, should they both be set.
   1540 </p>
   1541 <pre>
   1542 &commat;BindingAdapter("android:onViewAttachedToWindow")
   1543 public static void setListener(View view, OnViewAttachedToWindow attached) {
   1544     setListener(view, null, attached);
   1545 }
   1546 
   1547 &commat;BindingAdapter("android:onViewDetachedFromWindow")
   1548 public static void setListener(View view, OnViewDetachedFromWindow detached) {
   1549     setListener(view, detached, null);
   1550 }
   1551 
   1552 &commat;BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"})
   1553 public static void setListener(View view, final OnViewDetachedFromWindow detach,
   1554         final OnViewAttachedToWindow attach) {
   1555     if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) {
   1556         final OnAttachStateChangeListener newListener;
   1557         if (detach == null && attach == null) {
   1558             newListener = null;
   1559         } else {
   1560             newListener = new OnAttachStateChangeListener() {
   1561                 &commat;Override
   1562                 public void onViewAttachedToWindow(View v) {
   1563                     if (attach != null) {
   1564                         attach.onViewAttachedToWindow(v);
   1565                     }
   1566                 }
   1567 
   1568                 &commat;Override
   1569                 public void onViewDetachedFromWindow(View v) {
   1570                     if (detach != null) {
   1571                         detach.onViewDetachedFromWindow(v);
   1572                     }
   1573                 }
   1574             };
   1575         }
   1576         final OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view,
   1577                 newListener, R.id.onAttachStateChangeListener);
   1578         if (oldListener != null) {
   1579             view.removeOnAttachStateChangeListener(oldListener);
   1580         }
   1581         if (newListener != null) {
   1582             view.addOnAttachStateChangeListener(newListener);
   1583         }
   1584     }
   1585 }
   1586 </pre>
   1587 <p>
   1588   The above example is slightly more complicated than normal because View uses add and remove
   1589   for the listener instead of a set method for {@link android.view.View.OnAttachStateChangeListener}.
   1590   The <code>android.databinding.adapters.ListenerUtil</code> class helps keep track of the previous
   1591   listeners so that they may be removed in the Binding Adaper.
   1592 </p>
   1593 <p>
   1594   By annotating the interfaces <code>OnViewDetachedFromWindow</code> and
   1595   <code>OnViewAttachedToWindow</code> with
   1596   <code>&commat;TargetApi(VERSION_CODES.HONEYCOMB_MR1)</code>, the data binding code
   1597   generator knows that the listener should only be generated when running on Honeycomb MR1
   1598   and new devices, the same version supported by
   1599   {@link android.view.View#addOnAttachStateChangeListener}.
   1600 </p>
   1601 <h2 id="converters">
   1602   Converters
   1603 </h2>
   1604 
   1605 <h3 id="object_conversions">
   1606   Object Conversions
   1607 </h3>
   1608 
   1609 <p>
   1610   When an Object is returned from a binding expression, a setter will be chosen
   1611   from the automatic, renamed, and custom setters. The Object will be cast to a
   1612   parameter type of the chosen setter.
   1613 </p>
   1614 
   1615 <p>
   1616   This is a convenience for those using ObservableMaps to hold data. for
   1617   example:
   1618 </p>
   1619 
   1620 <pre>
   1621 &lt;TextView
   1622    android:text=&apos;&commat;{userMap["lastName"]}&apos;
   1623    android:layout_width="wrap_content"
   1624    android:layout_height="wrap_content"/&gt;
   1625 </pre>
   1626 
   1627 <p>
   1628 The <code>userMap</code> returns an Object and that Object will be automatically cast to
   1629   parameter type found in the setter <code>setText(CharSequence)</code>. When there
   1630   may be confusion about the parameter type, the developer will need
   1631   to cast in the expression.
   1632 </p>
   1633 
   1634 <h3 id="custom_conversions">Custom Conversions</h3>
   1635 
   1636 <p>
   1637   Sometimes conversions should be automatic between specific types. For
   1638   example, when setting the background:
   1639 </p>
   1640 
   1641 <pre>
   1642 &lt;View
   1643    android:background="&commat;{isError ? &commat;color/red : &commat;color/white}"
   1644    android:layout_width="wrap_content"
   1645    android:layout_height="wrap_content"/&gt;
   1646 </pre>
   1647 <p>
   1648   Here, the background takes a <code>Drawable</code>, but the color is an
   1649   integer. Whenever a <code>Drawable</code> is expected and an integer is
   1650   returned, the <code>int</code> should be converted to a
   1651   <code>ColorDrawable</code>. This conversion is done using a static method
   1652   with a BindingConversion annotation:
   1653 </p>
   1654 
   1655 <pre>
   1656 &commat;BindingConversion
   1657 public static ColorDrawable convertColorToDrawable(int color) {
   1658    return new ColorDrawable(color);
   1659 }
   1660 </pre>
   1661 <p>
   1662   Note that conversions only happen at the setter level, so it is <strong>not
   1663   allowed</strong> to mix types like this:
   1664 </p>
   1665 
   1666 <pre>
   1667 &lt;View
   1668    android:background="&commat;{isError ? &commat;drawable/error : &commat;color/white}"
   1669    android:layout_width="wrap_content"
   1670    android:layout_height="wrap_content"/&gt;
   1671 </pre>
   1672