私はデータバインディングとmvvmを学んでいます。 BaseViewModel.kt
にisLoading
フラグや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
これが不可能な場合、私が見ることができる唯一の選択肢は、インクルードを削除し、プログレスバーとテキストをコピーしてすべてのビューモデルに貼り付けることです。これはあまり良くありません。
バインディングにキャストする必要があると思います。
<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}"
それでも解決策がない場合は、コードをチェックして、「bind」属性の名前が含まれているレイアウトで使用されているものと同じかどうかを確認してください。
<include
...
bind:viewModel="@{viewModel}"/>
そして
<data>
...
<variable
name="viewModel"
type="core.sdk.ui.base.BaseViewModel" />
</data>