子类的Android数据绑定

dev*_*oid 2 data-binding android parent-child

我必须上课:

public class Product {
  private int id;
  private String title;
  .............
  .............
}
Run Code Online (Sandbox Code Playgroud)

其他类如下:

public class CatalogItem extends Product {
   private int price;
   private String[] colors;
   .............
   .............
}
Run Code Online (Sandbox Code Playgroud)

在布局中,我想访问子类和父类的所有属性。

<layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="catalogItem "
            type="com.appdemo.db.entity.CatalogItem" />
   </data>
   <TextView
            android:id="@+id/productIdTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text="@{((com.appdemo.db.entity.Product) catalogItem).id}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
     ..................
     ..................
</layout>
Run Code Online (Sandbox Code Playgroud)

但是在数据绑定的情况下,却无法访问父类的属性。访问父类属性的正确方法是什么?

Sam*_*Sam 5

我相信您的问题是您的访问器不是公开的,并且在您进行类型转换时标记为 @Bindable,这很好,但是如果您发布 Pseduo 代码并且仍然卡住。我会让你知道我遇到了什么。

我发现了同样的问题,并在此问题上将头撞在墙上几个小时。我最终找到了一篇文章,其中有人谈到了 xml 中的类型转换。我准备传入子类和父类,就像声明它们一样,只需在构造函数中将它们设置为同一个对象。这是一种选择,只是不是一个优雅的选择。

首先,问题 xml 数据绑定不够智能,无法在编译时为 xml 创建数据类来抓取基类。这是一个短暂的未来,希望他们能尽快解决。如果有人在解决此问题后阅读本文,请随时更新帖子;)。

所以现在的解决方案基本上你有两个选择。

选项1

您可以像这样在 xml 中声明这两个变量:

 <data>
    <variable name="parentPropertyModel" type="com.mypath.BaseModel"/>
    <variable name="childPropertyModel" type="com.mypath.ChildModel"/>
</data>
Run Code Online (Sandbox Code Playgroud)

然后在您的 onCreate 中,您将同时使用两者。

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    mBinding = DataBindingUtil.setContentView(this, R.layout.activity_myscreen)
    mBinding.childPropertyModel = mSelectedObject
    mBinding.parentPropertyModel = mSelectedObject
}
Run Code Online (Sandbox Code Playgroud)

那么当然你使用你所接触的财产所需的那个。

android:text="@{childPropertyModel.fieldInChild}"
android:hint="@{parentPropertyModel.fieldInParent}"
Run Code Online (Sandbox Code Playgroud)

现在我不了解你,但我不喜欢这个,因为它给未来的开发人员带来了两个不同对象的错觉,如果你没有很好地命名它们,可能会造成混淆。所以我选择了选项 2。

选项 2

类型转换,我试了一下,它奏效了:)。你不会得到智能感知,所以你只需要知道你在输入什么,但我向你保证它有效。

像以前一样声明你的变量。

<data>
     <variable name="classModel" type="com.mypath.ChildModel"/>
</data>
Run Code Online (Sandbox Code Playgroud)

然后像以前一样在您的 onCreate 中设置它,但现在只有一个对象。

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_myscreen)
        mBinding.classModel = mSelectedObject
 }
Run Code Online (Sandbox Code Playgroud)

然后根据需要使用它,像这个完全限定的路径一样进行转换。

android:text="@{classModel.fieldInChild}"
android:hint="@{((com.mypath.BaseModel)classModel).fieldInParent}"
Run Code Online (Sandbox Code Playgroud)

就是这样,我敢肯定,这不是你见过的最漂亮的东西,但它确实有效。

我希望这可以节省一些人在那里我忍受的头痛时间,哈哈。

快乐编码。