talk:title="@{dataBinding}

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

 talk:title="@{dataBinding}

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.

0ebcda68732e9ed18d903d34bcf62b64?s=128

Lisa Wray

February 09, 2016
Tweet

Transcript

  1. 2.

    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. 11.

    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. 14.

    <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. 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
  5. 18.

    100% generated Java code Uses bitwise flags to mark ‘dirty’

    One traversal to find all views How does it work? @{dataBinding}
  6. 20.
  7. 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
  8. 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
  9. 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 …
  10. 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}"
  11. 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}" />
  12. 31.

    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>
  13. 33.

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

    { public final ObservableField<VOTE> vote = new ObservableField(); } voteState.vote.set(VOTE.DOWNVOTE) Persistent binding
  14. 34.

    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