【问题标题】:Viewstub cannot pass stringresource to databindingViewstub 无法将 stringresource 传递给数据绑定
【发布时间】: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_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="@{vBility}">

        <com.example.app.presentation.util.view.FixedInputTextLayout
            android:id="@+id/app_default_et"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="@dimen/wrapContent"
            android:layout_height="wrap_content"
            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_width="match_parent"
                android:layout_height="wrap_content"
                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_width="@dimen/wrapContent"
    android:layout_height="wrap_content"
    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,我不能直接将任何字符串传递给我的数据绑定?

【问题讨论】:

    标签: android android-layout android-xml android-databinding viewstub


    【解决方案1】:

    这是您在将字符串资源传递到 ViewStub 时遇到问题的简短答案:在您发布的代码中,导致问题的部分是 appDefaultCompanyNameEt.getResources()。这里appDefaultCompanyNameEtViewStubProxy,它不是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_width="match_parent"
            android:layout_height="wrap_content"
            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_width="wrap_content"
            android:layout_height="wrap_content"
            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_width="300dp"
                android:layout_height="wrap_content"
                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_width="match_parent"
            android:layout_height="match_parent">
    
            <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。无论如何,你发现了一个错误。我会寻找你的答案。
    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2016-04-15
    相关资源
    最近更新 更多