安卓数据绑定中的“DataBindingComponent”类是什么?

21
我在官方API文档中看到了DataBindingComponent。

https://developer.android.com/reference/android/databinding/DataBindingUtil.html

这个接口是在编译期间生成的,包含了所有使用的实例BindingAdapters的getter。当一个BindingAdapter是一个实例方法时,必须实例化实现该方法的类的实例。此接口将为每个具有名称get*的类生成getter,其中*是声明BindingAdapter类/接口的简单类名。名称冲突将通过向getter添加数字后缀来解决。
该类的实例也可以作为静态或实例BindingAdapters的第一个参数传入。
如果使用Dagger 2,则开发人员应扩展此接口并将扩展接口注释为Component。
然而,在网上找不到任何关于此类用法的示例。有人知道它是什么以及如何使用吗?
我尝试编写一些简单代码并进行调试,以查看它是什么,但它显示变量a为空变量。
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
    android.databinding.DataBindingComponent a = DataBindingUtil.getDefaultComponent();
    setContentView(binding.getRoot());
}

您可以遵循这个官方指南 https://developer.android.com/topic/libraries/data-binding/index.html 或者 这个教程 http://www.survivingwithandroid.com/2015/08/android-data-binding-tutorial-2.html - Shadow Droid
1
我知道如何使用Android数据绑定,但是我看到“DataBindingUtil”类中的一些方法中使用了“DataBindingComponent”类。我想知道这是什么以及如何使用它。 - Long Ranger
2个回答

25

根据文档,我们得知:

在编译期间生成此接口,包含所有已使用的实例 BindingAdapters 的 getter。当 BindingAdapter 是实例方法时,必须实例化实现该方法的类的实例。将为每个具有名称 get* 的类(其中 * 是声明 BindingAdapter 类/接口的简单类名)生成一个 getter 的接口。名称冲突将通过为 getter 添加数字后缀来解决。

此类的实例也可以作为静态或实例 BindingAdapters 的第一个参数传递。

如果使用 Dagger 2,则应扩展此接口并将扩展接口注释为 Component。

这告诉我们此接口用于生成并注入实现自定义@BindingAdapter 方法的工厂实例。通过这种方式,您可以为不同情况或布局配置数据绑定,或向其提供更一般的状态。如果您查看 Android Studio 中的默认 DataBindingComponent 类,则会发现它位于 build/generated/source/apt/dev

您可以使用以下方法与 DataBindingComponent

假设您定义了一个接口如下:

public interface Foo {
    @BindingAdapter("foobar")
    void fooBar(View view, String baz);
}

会生成一个 android.databinding.DataBindingComponent 接口。

public interface DataBindingComponent {
    di.pkg.Foo getFoo();
}

现在您的数据绑定中会使用此@BindingAdapter宿主,但您需要自己实现接口并像上面给出的方法之一一起使用它。

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);
            }
        };
    }
});

在你的示例中,DataBindingUtil.getDefaultComponent() 返回 null,因为你从未自己设置默认组件。


你的第三段代码片段显示了一个编译时错误,因为“Foo”类不是“android.databinding.DataBindingComponent”的类型。如果我理解正确的话,这个DataBindingComponent可以用来开发第三方数据绑定库,因为该接口可以被实现,而且组件也可以手动设置(这意味着可以使用面向对象编程进行开发)。 - Long Ranger
1
你是正确的。我忘记实现组件本身了。我不太确定 @BindingAdapter 如何与库一起使用。DataBindingComponent 可以与依赖注入一起使用,而不是静态方法。这样可以更轻松地改变实现方式。 - tynn
感谢您的解释。我会尝试创建一个示例,使绑定更加灵活,因为指南引导开发人员编写一些静态方法来进行绑定,而不是将其作为对象或可扩展的方式。 - Long Ranger

25

阅读了@tynn的答案后,DataBindingComponent类也可以作为数据绑定方法的“对象”范围。与以静态方式设置所有方法不同,以下示例可用于扩展和自定义。例如,我们为ImageView、TextView和View类型设置了3个绑定方法。您可以首先设置接口(就像Retrofit 2为API设置接口一样)。

1. 首先设置3个接口

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. 根据 @tynn 所提到的,DataBindingComponent.java文件应该自动更新,更新后的内容如下所示。

如果您查看Android Studio中默认的DataBindingComponent类,您会发现它位于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. 构建自己的绑定实现方法。

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. 设置自己的数据绑定组件

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. 在应用程序中设置默认的 DataBindingComponent

public class MyApplication extends Application {
    public void onCreate() {
        super.onCreate();
        DataBindingUtil.setDefaultComponent(new MyOwnDefaultDataBindingComponent());
    }
}

使用这种方法制作自定义数据绑定应该是没有问题的,并且可以进行扩展。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接