web-dev-qa-db-fra.com

Héritage variable de liaison de données avec une disposition incluse

J'apprends la liaison de données et MVVM. J'ai un problème où je voudrais qu'un BaseViewModel.kt inclue des variables liées à l'interface utilisateur, telles qu'un indicateur isLoading et loadingText. Quand une requête réseau est faite, je règle isLoading sur true et un enfant de mon modèle de vue de base doit définir le texte. Par exemple, pour un LoginViewModel.kt, le texte pourrait être «se connecter». Est-il possible de passer ces variables à une disposition de base incluse?

Donc, un login_activity.xml pourrait inclure ceci dans sa mise en page:

    <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}"/>

Maintenant, je veux que mon progress_bar.xml soit Nice et générique et utilise le modèle de vue de base:

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

L'erreur que je reçois est quelque chose comme

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

Si ce n'est pas possible, la seule alternative que je vois est de supprimer l'inclusion, de copier et coller la barre de progression + le texte dans chaque modèle d'affichage qui n'est pas très joli.

8
Daniel Wilson

Je pense que vous devriez le jeter dans la reliure:

<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}"/>
4

Vous pouvez utiliser une liaison avec include comme

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>

En utilisant

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

vous pouvez également passer la valeur dure comme

app:visibility="@{false}"
app:text="@{@string/loading_text}"
2
Linh