I have seen the DataBindingComponent in the official API doc.
https://developer.android.com/reference/android/databinding/DataBindingUtil.html
Th
After reading the answer from @tynn , the DataBindingComponent class can also be as "object" scope of data binding method. Instead of setting all the method in static way, the following example can be used to be extendable and custom. For example, we setup 3 binding methods for ImageView, TextView and View type. You can setup the interface first ( like Retrofit 2 setup interface for API)
1. Setup 3 interface first
ImageViewBindingInterface.java
public interface ImageViewBindingInterface {
@BindingAdapter({"bind:imageUrl", "bind:error"})
public void loadImage(ImageView view, String url, Drawable error);
}
TextViewBindingInterface.java
public interface TextViewBindingInterface {
@BindingAdapter({"bind:font"})
void setFont(TextView textView, String fontName);
}
ViewBindingInterface.java
public interface ViewBindingInterface {
@BindingAdapter("android:paddingLeft")
public void setPaddingLeft(View view, int padding);
@BindingAdapter("android:onViewAttachedToWindow")
public void setListener(View view, ViewBindingAdapter.OnViewAttachedToWindow attached);
}
2. The DataBindingComponent.java should be updated automatically as @tynn mentioned like the following.
If you have a look at the default DataBindingComponent class in Android Studio you find it located in build/generated/source/apt/dev.
public interface DataBindingComponent {
example.com.testerapplication.binding.ViewBindingInterface getViewBindingInterface();
example.com.testerapplication.binding.TextViewBindingInterface getTextViewBindingInterface();
example.com.testerapplication.binding.ImageViewBindingInterface getImageViewBindingInterface();
}
3. Build your own implementation method for binding.
BaseImageViewBinding.java
public class BaseImageViewBinding implements ImageViewBindingInterface{
@Override
public void loadImage(ImageView view, String url, Drawable error) {
Picasso.with(view.getContext()).load(url).error(error).into(view);
}
}
BaseTextViewBinding.java
public class BaseTextViewBinding implements TextViewBindingInterface {
@Override
public void setFont(TextView textView, String fontName) {
textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}
}
BaseViewBinding.java
public class BaseViewBinding implements ViewBindingInterface {
@Override
public void setPaddingLeft(View view, int padding) {
view.setPadding(padding,
view.getPaddingTop(),
view.getPaddingRight(),
view.getPaddingBottom());
}
@Override
public void setListener(View view, ViewBindingAdapter.OnViewAttachedToWindow attached) {
}
}
4. Set your OwnDatabindingComponent
public class MyOwnDefaultDataBindingComponent implements android.databinding.DataBindingComponent {
@Override
public ViewBindingInterface getViewBindingInterface() {
return new BaseViewBinding();
}
@Override
public TextViewBindingInterface getTextViewBindingInterface() {
return new BaseTextViewBinding();
}
@Override
public ImageViewBindingInterface getImageViewBindingInterface() {
return new BaseImageViewBinding();
}
}
5. Setup your default DataBindingComponent in the Application
public class MyApplication extends Application {
public void onCreate() {
super.onCreate();
DataBindingUtil.setDefaultComponent(new MyOwnDefaultDataBindingComponent());
}
}
Using this method should be fine to make the custom data binding in a custom way and can be extensible.
From the documentation we know
This interface is generated during compilation to contain getters for all used instance BindingAdapters. When a BindingAdapter is an instance method, an instance of the class implementing the method must be instantiated. This interface will be generated with a getter for each class with the name get* where * is simple class name of the declaring BindingAdapter class/interface. Name collisions will be resolved by adding a numeric suffix to the getter.
An instance of this class may also be passed into static or instance BindingAdapters as the first parameter.
If using Dagger 2, the developer should extend this interface and annotate the extended interface as a Component.
This tells us this interface is used and generated for injecting a factory for instances implementing custom @BindingAdapter
methods. Like this you can configure the data bindings for different situations or layouts or supply it with a more general state. If you have a look at the default DataBindingComponent
class in Android Studio you find it located in build/generated/source/apt/dev.
The methods you can use with the DataBindingComponent
are
Considering you define an interface like
public interface Foo {
@BindingAdapter("foobar")
void fooBar(View view, String baz);
}
an android.databinding.DataBindingComponent
interface gets generated
public interface DataBindingComponent {
di.pkg.Foo getFoo();
}
This @BindingAdapter
host now gets used in your data bindings, but you need to implement the interface yourself and use it with one of the methods given above like
DataBindingUtil.setDefaultComponent(new DataBindingComponent(){
@Override
public Foo getFoo() {
return new Foo() {
@Override
public void fooBar(View view, String baz) {
if (view instanceof TextView) ((TextView) view).setText(baz);
}
};
}
});
In your example you get null from DataBindingUtil.getDefaultComponent()
because you've never set the default component yourself.