web-dev-qa-db-ja.com

レイアウトが含まれるデータバインディング変数の継承

私はデータバインディングとmvvmを学んでいます。 BaseViewModel.ktisLoadingフラグやloadingTextなどのUI関連の変数を含めたいという問題があります。ネットワーク要求が行われると、isLoadingをtrueに設定し、ベースビューモデルの子がテキストを設定する必要があります。たとえば、LoginViewModel.ktの場合、テキストは「ログイン中」の場合があります。これらの変数を含まれている基本レイアウトに渡すことは可能ですか?

したがって、login_activity.xmlはレイアウトにこれを含めることができます。

    <data>
        <import type="Android.view.View" />
        <variable
            name="viewModel"
            type="core.sdk.ui.login.LoginViewModel" />
    </data>

<!-- Various click listeners using the viewModel variable -->

    <include
        Android:id="@+id/progress_include"
        layout="@layout/progress_bar"
        Android:visibility="@{viewModel.isLoading ? View.VISIBLE : View.GONE}"
        bind:viewModel="@{viewModel}"/>

ここで、progress_bar.xmlを適切で一般的なものにし、ベースビューモデルを使用します。

<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
tools:context="core.sdk.ui.login.LoginActivity">

<data>

    <import type="Android.view.View" />

    <variable
        name="viewModel"
        type="core.sdk.ui.base.BaseViewModel" />

</data>

<LinearLayout
    Android:id="@+id/circular_progress"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_gravity="center"
    Android:gravity="center"
    Android:orientation="vertical">

    <Android.support.v4.widget.ContentLoadingProgressBar
        style="@style/Widget.AppCompat.ProgressBar"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content" />

    <TextView
        Android:id="@+id/progress_text"
        style="@style/TextAppearance.AppCompat.Subhead"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:fontFamily="sans-serif-thin"
        Android:gravity="center_horizontal"
        Android:text="@{viewModel.loadingText}"
        Android:textStyle="italic"
        tools:text="loading..." />
</LinearLayout>

私が得るエラーは次のようなものです

****/ data binding error ****msg:Cannot find the setter for attribute 'bind:viewModel' with parameter type core.sdk.ui.login.LoginViewModel

これが不可能な場合、私が見ることができる唯一の選択肢は、インクルードを削除し、プログレスバーとテキストをコピーしてすべてのビューモデルに貼り付けることです。これはあまり良くありません。

9
Daniel Wilson

バインディングにキャストする必要があると思います。

<include
    Android:id="@+id/progress_include"
    layout="@layout/progress_bar"
    Android:visibility="@{viewModel.isLoading ? View.VISIBLE : View.GONE}"
    bind:viewModel="@{(core.sdk.ui.base.BaseViewModel)viewModel}"/>

インクルードのようなバインディングを使用できます

loading_view.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    >

    <data>

        <import type="Android.view.View"/>

        <variable
            name="visibility"
            type="boolean"
            />

        <variable
            name="text"
            type="String"
            />
    </data>

    <LinearLayout
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:background="#ff0"
        Android:gravity="center_horizontal"
        Android:orientation="vertical"
        Android:visibility="@{visibility?View.VISIBLE:View.GONE}"
        >
        <ProgressBar
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            />
        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="match_parent"
            Android:text="@{text}"
            tools:text="AA"
            />
    </LinearLayout>
</layout>

使用する

<include
        layout="@layout/loading_view"
        app:visibility="@{viewModel.loadingCondition}"
        app:text='@{"AA"}'
        />

次のような難しい値を渡すこともできます

app:visibility="@{false}"
app:text="@{@string/loading_text}"
3
Phan Van Linh

それでも解決策がない場合は、コードをチェックして、「bind」属性の名前が含まれているレイアウトで使用されているものと同じかどうかを確認してください。

<include
       ...
        bind:viewModel="@{viewModel}"/>

そして

<data>
    ...
    <variable
        name="viewModel"
        type="core.sdk.ui.base.BaseViewModel" />

</data>
0
Aleyam