1page.title=Data Binding Guide
2page.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
146versions 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>
149or 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 isn’t 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 it’s always a great idea to test your
175    app thoroughly when adopting new libraries or tools.
176    </li>
177    <li>
178    We’re 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
192repository in the Android SDK manager. </p>
193
194<p>The Data Binding plugin requires Android Plugin for Gradle <strong>1.3.0-beta4
195or 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
200support 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>
223allprojects {
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>
235apply plugin: &apos;com.android.application&apos;
236apply 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 TextView’s 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  Let’s assume for now that you have a plain-old Java object (POJO) for User:
302</p>
303
304<pre>
305public 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>
321public 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 TextView’s <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 layout’s 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
361protected 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  You’re done! Run the application and you’ll see Test User in the UI.
370  Alternatively, you can get the view via:
371</p>
372
373<pre>
374MainActivityBinding 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>
382ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
383//or
384ListItemBinding 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;
510511&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>
729android:text="&commat;{String.valueOf(index + 1)}"
730android:visibility="&commat;{age &amp;lt; 13 ? View.GONE : View.VISIBLE}"
731android: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;
826827android:text="&commat;{list[index]}"
828829android:text="&commat;{sparse[index]}"
830831android: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>
844android: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>
853android:text="&commat;{map[`firstName`}"
854android: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>
866android: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>
873android:text="&commat;{&commat;string/nameFormat(firstName, lastName)}"
874android: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
885android: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>
1029private 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>
1082private 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>
1095user.firstName.set("Google");
1096int 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>
1110ObservableArrayMap&lt;String, Object&gt; user = new ObservableArrayMap&lt;&gt;();
1111user.put("firstName", "Google");
1112user.put("lastName", "Inc.");
1113user.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;
11241125&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>
1139ObservableArrayList&lt;Object&gt; user = new ObservableArrayList&lt;&gt;();
1140user.add("Google");
1141user.add("Inc.");
1142user.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;
11541155&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>
1190MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater);
1191MyLayoutBinding 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>
1199MyLayoutBinding 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>
1207ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId,
1208    parent, attachToParent);
1209ViewDataBinding 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>
1247public final TextView firstName;
1248public 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>
1276public abstract com.example.User getUser();
1277public abstract void setUser(com.example.User user);
1278public abstract Drawable getImage();
1279public abstract void setImage(Drawable image);
1280public abstract String getNote();
1281public 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>
1331public 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>
1371For an attribute, data binding tries to find the method setAttribute. The
1372namespace 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")
1438public 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"})
1461public 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}”
1467app: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")
1491public 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")
1506public 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)
1528public interface OnViewDetachedFromWindow {
1529    void onViewDetachedFromWindow(View v);
1530}
1531
1532&commat;TargetApi(VERSION_CODES.HONEYCOMB_MR1)
1533public 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")
1543public static void setListener(View view, OnViewAttachedToWindow attached) {
1544    setListener(view, null, attached);
1545}
1546
1547&commat;BindingAdapter("android:onViewDetachedFromWindow")
1548public static void setListener(View view, OnViewDetachedFromWindow detached) {
1549    setListener(view, detached, null);
1550}
1551
1552&commat;BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"})
1553public 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>
1628The <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
1657public 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