Let’s compare Butterknife and Data Binding libraries, which one is more advanced in 2017? If you’re not familiar with those two, in few words: they make your layout building experience better. And when comparing them I’ll go right from setting up and cover every basic aspect so you’ll learn how to use both of them!
For Butterknife you need to add those dependencies to build.gradle
compile ‘com.jakewharton:butterknife:8.6.0’
annotationProcessor ‘com.jakewharton:butterknife-compiler:8.6.0’
Here you’ll just add those inside android scope in build.gradle
android{
…
dataBinding {
enabled true
}
}
And then wrap all your layouts with layout tag so it’s the root tag everywhere
<layout>
<LinearLayout>…</LinearLayout>
</layout>
What you would do in plain Android framework to find views in layout is use this method
findViewById(R.id.textView);
Then you cast it to the right type, keep it as local variable or save to field, this is really lots of work for big layouts
With Butterknife you can just declare fields with this annotation
public class MyActivity{
@BindView(R.id.textView) TextView text;
…
}
And declare each view as field this way, no need for findViewById method. Now if you compare this to old school method — you saved yourself 50% of lines if you save views as fields. Twice less lines.
But still, if you have 20 views — you’ll have those 20 ugly fields on top of the class, that’s just views, how about variables etc?
Now that’s the next level, here you need to do some changes though. Replace default setContentView with this
@Override
protected void onCreate(Bundle savedInstanceState) {
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
…
}
As you see there’s some ActivityMainBinding class — this class is generated for your layouts, it’s based on layout name converted to camel case adding Binding at the end. It happens when you wrap your layout with layout tag. If you have layout called layout.xml — you’d have LayoutBinding class generated
Now to access any of your views you just use
binding.textView
If you realized the advantage of Data Binding already — it’s you have 2 lines of code max.You just save that binding variable as field if you need and can assess any of you fields anywhere within this class
Let’s say we have 20 views in our layout and we want them to be accessible in any method within a class, so we need to have them as fields.
With findViewById you’d have 40 lines of code, with Butterknife — 20, with DataBinding — 2. Two lines! Data Binding is obvious winner here
If you look into Butterknife doc — basically there isn’t much more. OnClick annotation which doesn’t even need any library because you can use android:onClick attribute for your views right in XML
Resource binding, which some people use, there isn’t such in Data Binding. And basically that’s it
Where with Data Binding it’s just a beginning. You can move your logic into XML files which is more natural approach when building layouts
Let’s say you have a Movie model with 20 fields and you want to display all of them in layout. Normally you’d call setText and any other methods in Java for each movie field. With Data Binding you can do this
<layout>
<data>
<variable
name=”movie”
type=”com.unifiedwaves.Movie”/>
</data>
<TextView
…
android:text=”@{movie.name}”/>
</layouyt>
You add variable at the top of layout and then can set views right there. Name is a variable name in Movie class.
And to pass an object to your layout you call this method in Java, it’s generated for each of your variables
binding.setMovie(new Movie(…));
It’s not that this approach saves some lines of code, it’s that it’s more natural and you won’t need to go back and forth from Java to XML again and again when building layouts, writing Java. You just write layout, done with it, go to Java. Simple.
There’s way more Data Binding can offer, just one last thing I wanted to mention — custom attributes. You can create custom attributes for any view without actually extending those views by using Binding Adapters
One of my most favorites — imageUrl. How many times you would want for Android framework to have this attribute where you just pass image url to ImageView and it just loads it? Well, when you’re just getting started you probably do.
Look at what we can do
@BindingAdapter(“app:imageUrl”)
public static void imageUrl(ImageView v, String url){
//Glide.with()…
}
<layout>
<data>
<variable
name=”movie”
type=”com.myhexaville.Movie”/>
</data>
<ImageView
…
app:imageUrl=”@{movie.imageUrl}”/>
</layouyt>
imageUrl is a String field variable of Movie model. We’ve just declared a custom attribute for ImageView. Once you pass movie object to your layout with binding.setMovie(movie) — your ImageView will load image url from movie object with Glide
And as for that static method — you can put it anywhere in your project you want. Literally anywhere, it will work
Data Binding came out soon after I started learning Android in 2015 so I used Butterknife for few times and when I saw Data Binding I realized — that’s the next level. Just look at simple accessing views.
Btw, if you use Kotlin — there’s Android Extensions for accessing views which works just like Data Binding, but with less overhead
Thanks for reading!