Upgrade to Pro — share decks privately, control downloads, hide ads and more …


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

More Decks by Lisa Wray

Other Decks in Programming


  1. textView.setCompoundDrawablesWithIntrinsicBounds( ContextCompat.getDrawable(this, R.drawable.cat), null, null, null); Problem: Repetitive Java boilerplate

    @{dataBinding} findViewById, casts setters are verbose/confusing toolbar = (Toolbar) findViewById(R.id.toolbar);
  2. Before: inflate and find views CollapsingToolbarLayout appBarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);

    ImageView backdropImageView = (ImageView) findViewById(R.id.backdrop); Button upvoteButton = (Button) findViewById(R.id.upvote); Button downvoteButton = (Button) findViewById(R.id.downvote); setContentView(R.layout.activity_pet_detail); After PetDetailBinding binding = DataBindingUtil.setContentView (this, R.layout.pet_detail);
  3. <Button app:selected=“@{vote == VOTE.UPVOTE}" android:tint=“@drawable/upvote_selector” /> Before:Java After:XML switch(pet.vote) {

    case UPVOTE: upvoteButton.setSelected(true); downvoteButton.setSelected(false); break; case DOWNVOTE: …
  4. 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
  5. 100% generated Java code Uses bitwise flags to mark ‘dirty’

    One traversal to find all views How does it work? @{dataBinding}
  6. @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
  7. 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
  8. 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 …
  9. <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}"
  10. @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}" />
  11. layout/family.xml <layout> … <include layout="@layout/pet" app:pet=“@{family.pet}" /> </layout> <include> layout/pet.xml

    <layout> <data> <variable name="pet" type="com.xwray.dogmeetscat.Pet"/> </data> … </layout>
  12. enum VOTE { UPVOTE, DOWNVOTE, NONE } public class VoteState

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

    extends BaseObservable { private VOTE vote; @Bindable getVote(); setVote(VOTE vote) { this.vote = vote; notifyChanged(BR.vote) } } Persistent binding