0ebcda68732e9ed18d903d34bcf62b64?s=47 Lisa Wray
February 09, 2016


A tour through the data binding framework's obvious and not-so-obvious perks. Reduce boilerplate, avoid NullPointerExceptions, decrease code complexity, and maybe even fix some Android pet peeves.


Lisa Wray

February 09, 2016


  1. “@{dataBinding}” talk:title= @{dataBinding} @lisawrayz

  2. textView.setCompoundDrawablesWithIntrinsicBounds( ContextCompat.getDrawable(this,, null, null, null); Problem: Repetitive Java boilerplate

    @{dataBinding} findViewById, casts setters are verbose/confusing toolbar = (Toolbar) findViewById(;
  3. Problem: Repetitive Java boilerplate @{dataBinding} findViewById, casts setters are verbose/confusing

    XML layout is limited Manually keep track of UI updates
  4. What is it? @{dataBinding} A framework to connect your model

    and your UI Once or persistently
  5. An XML attribute for every Java setter @{dataBinding} What else

    is it?
  6. Custom XML attributes @{dataBinding} What else is it?

  7. Overwrite Android XML attributes @{dataBinding} What else is it?

  8. An alternative to custom views @{dataBinding} What else is it?

  9. O.K., show me!

  10. Find the views Set custom font Set button colors Load

    and set the image Set title
  11. Before: inflate and find views CollapsingToolbarLayout appBarLayout = (CollapsingToolbarLayout) findViewById(;

    ImageView backdropImageView = (ImageView) findViewById(; Button upvoteButton = (Button) findViewById(; Button downvoteButton = (Button) findViewById(; setContentView(R.layout.activity_pet_detail); After PetDetailBinding binding = DataBindingUtil.setContentView (this, R.layout.pet_detail);
  12. Before:Java if (pet != null) { appBarLayout.setTitle(pet.getName()); } After:XML <

    app:title="@{}" >
  13. Before: Java Typeface lobster = FontCache.getInstance().get("LobsterTwo-Bold"); appBarLayout.setCollapsedTitleTypeface(lobster); appBarLayout.setExpandedTitleTypeface(lobster); After:XML <

    app:collapsedTitleTypeface="@{`LobsterTwo-Bold`}" app:expandedTitleTypeface=“@{`LobsterTwo-Bold`}" >
  14. <Button app:selected=“@{vote == VOTE.UPVOTE}" android:tint=“@drawable/upvote_selector” /> Before:Java After:XML switch( {

    case UPVOTE: upvoteButton.setSelected(true); downvoteButton.setSelected(false); break; case DOWNVOTE: …
  15. Before: Java Glide.with(this).load(pet.getImageUrl()).into(backdropImageView); After:XML <ImageView app:imageUrl="@{pet.imageUrl}"/>

  16. Making the connection

  17. PetDetailBinding binding = DataBindingUtil.setContentView (this, R.layout.pet_detail); Before: Java … <layout>

    <data> <variable name="pet" type="com.xwray.dogmeetscat.Pet"/> </data> After:XML </layout> binding.setPet(pet); PetDetailBinding binding = DataBindingUtil.setContentView (this, R.layout.pet_detail); Your old layout goes here Your model object
  18. 100% generated Java code Uses bitwise flags to mark ‘dirty’

    One traversal to find all views How does it work? @{dataBinding}
  19. layout/pet.xml generated: PetBinding.image .title .upvote @{dataBinding}

  20. @{ }

  21. Existing attributes Pet.getName() app:title="@{}"

  22. android:text android:textColor Existing attributes android:drawableLeft android:src … and many, many

  23. <Button app:selected=“@{vote == VOTE.UPVOTE}" android:tint=“@drawable/upvote_selector” /> Attributes for every Java

    setter View.setSelected()
  24. app:imageUrl="@{pet.imageUrl}" Custom attributes

  25. @BindingAdapter({"bind:imageUrl"}) public static void loadImage(ImageView view, String url) { Glide.with(view.getContext())

    .load(url) .into(view); } Bindings You pick The view you’re binding Attribute
  26. app:font Custom attributes @BindingAdapter({"bind:font"}) public static void setFont(TextView textView, String

    fontName) { Typeface type = FontCache.getInstance().get(fontName); textView.setTypeface(type); } Bindings Tinkerbell
  27. app:collapsedTitleTypeface="@{`LobsterTwo-Bold`}" app:expandedTitleTypeface="@{`LobsterTwo-Bold`}" Custom attributes @BindingAdapter("bind:expandedTitleTypeface") public static void setExpandedTitleTypeface( CollapsingToolbarLayout

    layout, String fontName) { Typeface type = FontCache.getInstance().get(fontName); layout.setExpandedTitleTypeface(type); } @BindingAdapter("bind:collapsedTitleTypeface") public static void setCollapsedTitleTypeface …
  28. <TextView android:drawableRight=“@{isCat ? @drawable/cat : @drawable/dog}” /> <View android:paddingRight=“@{2 *

    @dimen/margin}” /> <View android:paddingRight=“@{@dimen/margin + @dimen/image_width}” /> Evaluate simple expressions app:selected=“@{vote == VOTE.UPVOTE}"
  29. before: if (pet != null) { appBarLayout.setTitle(pet.getName()); } after: android:text=“@{}”

    Avoid NPEs android:text=“@{}”
  30. @BindingAdapter("android:indeterminateTint") public static void setIndeterminateTint( ProgressBar progressBar, int color) {

    Drawable toTint = progressBar.getIndeterminateDrawable().mutate(); toTint.setColorFilter(color, PorterDuff.Mode.SRC_IN); } Overwrite Android attributes <ProgressBar style="?android:attr/progressBarStyle" android:indeterminateTint="@{@color/pink}" />
  31. layout/family.xml <layout> … <include layout="@layout/pet" app:pet=“@{}" /> </layout> <include> layout/pet.xml

    <layout> <data> <variable name="pet" type="com.xwray.dogmeetscat.Pet"/> </data> … </layout>
  32. One way binding Model changes, view is updated Persistent binding

  33. enum VOTE { UPVOTE, DOWNVOTE, NONE } public class VoteState

    { public final ObservableField<VOTE> vote = new ObservableField(); } Persistent binding
  34. enum VOTE { UPVOTE, DOWNVOTE, NONE } public class VoteState

    extends BaseObservable { private VOTE vote; @Bindable getVote(); setVote(VOTE vote) { = vote; notifyChanged( } } Persistent binding
  35. “In beta”, you said “It’ll be fun”, you said

  36. Gradle integration Syntax highlighting Code completion (2.0.0-alpha5) View and debug

    generated code Android Studio and You
  37. Refactoring “Convert to data binding” shortcut “Clean project” required sometimes

    Still to come …
  38. Android Studio tips <layout xmlns:android="" xmlns:app="" xmlns:tools=""> tools:text=“Jane Doe” tools:ignore="UnusedAttribute"

    Declare namespaces in layout tag Use tools: prefix for layout preview Ignore lint warnings
  39. app/build.gradle android { dataBinding { enabled = true } }

    How do I get started?
  40. fonts: docs: @lisawrayz