Viewstub 无法将 stringresource 传递给数据绑定

Posted

技术标签:

【中文标题】Viewstub 无法将 stringresource 传递给数据绑定【英文标题】:Viewstub cannot pass stringresource to databinding 【发布时间】:2021-11-12 22:44:59 【问题描述】:

我正在尝试通过 xml 将“@string”和“@stringarray”传递给我的 viewtub 数据绑定,但它不起作用。我收到以下错误消息:

C:\Users\censored\androidStudioProjects\example\app\build\generated\source\kapt\debug\com\example\app\databinding\AppStandardContactFormBindingImpl.java:943: error: cannot find symbol
            if (this.appDefaultCompanyNameEt.isInflated()) this.appDefaultCompanyNameEt.getBinding().setVariable(BR.hint, appDefaultCompanyNameEt.getResources().getString(R.string.app_contact_form_company_name));
                                                                                                                                                 ^
  symbol:   method getResources()
  location: variable appDefaultCompanyNameEt of type ViewStubProxy

ViewStub 膨胀布局

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

    <data>
        <variable
            name="vBility"
            type="Boolean" />
        <variable
            name="vForm"
            type="String" />
        <variable
            name="hint"
            type="String" />
        <variable
            name="iType"
            type="Integer" />
        <variable
            name="mText"
            type="String" />
    </data>


    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_
        android:layout_
        android:visibility="@vBility">

        <com.example.app.presentation.util.view.FixedInputTextLayout
            android:id="@+id/app_default_et"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_
            android:layout_
            android:hint="@hint"
            android:visibility="@vBility"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:validate_form="@vForm">

            <com.google.android.material.textfield.TextInputEditText
                android:layout_
                android:layout_
                android:inputType="@iType"
                android:text="@=mText"
                android:textSize="@dimen/font_text_large" />

        </com.example.app.presentation.util.view.FixedInputTextLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

在viewstub中使用布局

<ViewStub
    android:id="@+id/app_default_company_name_et"
    android:layout_
    android:layout_
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:inflatedId="@+id/app_default_company_name_et"
    android:layout="@layout/app_standard_textinputlayout"
    android:visibility="@cValidator.companySwitchState"
    app:vBility="@cValidator.companySwitchState"
    app:vForm="@cValidator.etCompanyNameEM"
    app:hint="@@string/app_contact_form_company_name" <!-- THIS IS GIVING ME THE ERROR -->
    app:iType="@0x00000001"
    app:mText="@cValidator.etCompanyName"
    app:layout_constraintEnd_toStartOf="@+id/app_default_company_ust_et"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="@+id/margin_left"
    app:layout_constraintTop_toBottomOf="@+id/calibrate_user_data_company_text" />

当我将app:hint="@@string/app_contact_form_company_name" 更改为app:hint="@someClass.someString" 时,它可以工作。这是否意味着,如果它是一个 viewtub,我不能直接将任何字符串传递给我的数据绑定?

【问题讨论】:

【参考方案1】:

这是您在将字符串资源传递到 ViewStub 时遇到问题的简短答案:在您发布的代码中,导致问题的部分是 appDefaultCompanyNameEt.getResources()。这里appDefaultCompanyNameEt 是ViewStubProxy,它不是View,所以它没有关联的资源。结果,appDefaultCompanyNameEt.getResources() 失败。这个消息有点神秘,但这就是它的意思。

if (this.appDefaultCompanyNameEt.isInflated()) this.appDefaultCompanyNameEt.getBinding()
    .setVariable(BR.hint, appDefaultCompanyNameEt.getResources()  // fails!
    .getString(R.string.app_contact_form_company_name));

我相信这可以被认为是一个错误。那么什么是变通方法?

似乎在提供包含文件的绑定数据链接时更加小心。请参阅 George Mount 的 this Stack Overflow 回答。

所以,我们可以做的就是将 ViewStub 的内容放在一个包含的文件中,如下所示:

view_stub.xml

<layout>

    <data>

        <variable
            name="myData"
            type="String" />

    </data>

    <TextView
        android:layout_
        android:layout_
        android:hint="A hint"
        android:text="@myData"
        android:textSize="36sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</layout>

并在将包含在主布局中的布局文件中引用它:

included_layout.xml

<layout>

    <data>

        <variable
            name="myData"
            type="String" />

    </data>

    <FrameLayout
        android:layout_
        android:layout_
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ViewStub
            android:id="@+id/viewStub"
            android:layout_
            android:layout_
            android:inflatedId="@+id/inflatedViewStub"
            android:layout="@layout/view_stub"
            app:myData="@myData" />
    </FrameLayout>
</layout>

最后是主布局:

activity_main.xml

<layout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/topLayout"
        android:layout_
        android:layout_>

        <include
            android:id="@+id/included"
            layout="@layout/included_layout"
            app:myData="@@string/myStringData" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

如果我们定义一个字符串资源如下:

<string name="myStringData">My string data.</string>

然后这个布局就会显示出来

这是有效的,因为初始包含对字符串资源进行了良好的翻译。包含的文件只看到它处理好的字符串。

这有点复杂。我很想知道是否有更简单的方法。

【讨论】:

最简单的方法是不要使用“@string/bla_bla_bla”在你的类中创建另一个变量,然后从那里获取字符串。所以@myClass.myString。我明天会发布我的解决方案 @Andrew 我同意这会更容易,但在我看来,您希望将字符串资源直接传递到 ViewStub。无论如何,你发现了一个错误。我会寻找你的答案。

以上是关于Viewstub 无法将 stringresource 传递给数据绑定的主要内容,如果未能解决你的问题,请参考以下文章

ViewStub的使用

Android - ViewStub

使 ViewStub 覆盖 Activity

单个viewStub中的多个布局

Android中文API-ViewStub

从源代码角度分析ViewStub 疑问与原理