I have been using findViewById
and then ButterKnife to bind views. Recently, I came across this article: https://proandroiddev.com/new-in-android-viewbindings-the-difference-from-databinding-library-bef5945baf5e and am not quite sure how to use it.
I tried doing it but it does not seem to work in Android Studio 3.4.2
val binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
then afterwards using these values, as an example :
binding.button....
binding.textView....
There is a couple of things you should do and I try to make it organized and listed: (Based on Android Developers docs from this link and my personal experiences)
You need to use Android Studio 3.6 canary11+ (I'm currently using Android Studio 4 and it is doing the job well for me)
You can find it from here: https://developer.android.com/studio/archive
You need to upgrade your Gradle wrapper to Gradle "5.6.4" and Gradle build tool to "3.6.0-rc01", higher versions also work so don't be afraid to be updated
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
dependencies {
...
classpath 'com.android.tools.build:gradle:3.6.0-rc01'
}
android {
...
buildFeatures {
viewBinding true
}
}
tools:viewBindingIgnore="true"
attribute to the root view of that layout file: <LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
If view binding is enabled for a module, a binding class is generated for each XML layout file that the module contains. Each binding class contains references to the root view and all views that have an ID. The name of the binding class is generated by converting the name of the XML file to camel case and adding the word "Binding" to the end.
For example, given a layout file called result_profile.xml
:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
The generated binding class is called ResultProfileBinding
. This class has two fields: a TextView
called name
and a Button
called button
. The ImageView
in the layout has no ID, so there is no reference to it in the binding class.
Every binding class also includes a getRoot()
method, providing a direct reference for the root view of the corresponding layout file. In this example, the getRoot()
method in the ResultProfileBinding
class returns the LinearLayout
root view.
private ResultProfileBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ResultProfileBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
}
private FragmentHousesBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentHousesBinding.inflate(inflater, container, false);
init();
return binding.getRoot();
}
HouseCardPropertyFragmnetBinding binding;
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
binding = HouseCardPropertyFragmnetBinding.inflate(LayoutInflater
.from(parent.getContext()), parent, false);
return new Holder(binding);
}
@Override
public void onBindViewHolder(@NonNull HouseAdapter.Holder holder, int position) {
holder.bindData(getItem(position));
}
class Holder extends RecyclerView.ViewHolder {
HouseCardPropertyFragmnetBinding view;
Holder(@NonNull HouseCardPropertyFragmnetBinding v) {
super(v.getRoot());
view = v;
}
void bindData(Tag item) {
view.tagTxt.setText(item.Name);
}
}
that's it you are free from the findViewById
from now on
;)