子类的Android数据绑定

时间:2018-04-16 13:30:10

标签: android data-binding parent-child

我必须上课:

public class Product {
  private int id;
  private String title;
  .............
  .............
}

其他课程如下:

public class CatalogItem extends Product {
   private int price;
   private String[] colors;
   .............
   .............
}

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

<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>

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

4 个答案:

答案 0 :(得分:2)

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

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

首先是问题 xml数据绑定不够聪明,无法在对xml进行编译时使用数据类创建来爬网基类。这是一个短暂的希望,希望他们能尽快解决。如果有人在解决此问题后阅读了此内容,请随时更新该帖子;)。

所以现在为解决方案 基本上,您有两个选择。

选项1

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

 <data>
    <variable name="parentPropertyModel" type="com.mypath.BaseModel"/>
    <variable name="childPropertyModel" type="com.mypath.ChildModel"/>
</data>

然后在onCreate中,请同时使用两者。

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

然后,您当然可以使用要触摸的属性所需的那个。

android:text="@{childPropertyModel.fieldInChild}"
android:hint="@{parentPropertyModel.fieldInParent}"

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

选项2

强制类型转换,我试了一下,就可以了:)。您将不会获得智能感知,因此您只需要知道您要输入的内容即可,但是我向您保证,它可以正常工作。

像以前一样声明变量。

<data>
     <variable name="classModel" type="com.mypath.ChildModel"/>
</data>

然后像以前一样在onCreate中进行设置,但现在仅设置一个对象。

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

然后根据需要使用它进行这种完全限定的路径转换。

android:text="@{classModel.fieldInChild}"
android:hint="@{((com.mypath.BaseModel)classModel).fieldInParent}"

就是这样,不是我确定的最漂亮的东西,但是它可以工作。

我希望这可以节省一个人,让我忍受数小时的头痛之苦。

快乐的编码。

答案 1 :(得分:0)

将id中的product class设为public,并提供数据并绑定到xml。

public int id;

in xml

 android:text="@{catalogItem.id}"

答案 2 :(得分:0)

没有这样的问题来访问任何属性,它不是所有与其访问修饰符相关的,它只需要适当的getter方法,可以从Binding类访问。由于id是int,它只需要String转换器。

答案 3 :(得分:-1)

使Parent类的字段受到保护。子类只能访问受保护或公共字段。

protected int id;