Let's say I have the following layout files:
first_layout.xml
<layout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/title_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First layout title"/>
<include
layout="@layout/reusable_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
second_layout.xml
<layout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/title_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second layout title"/>
<include
layout="@layout/reusable_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
reusable_layout.xml
<layout>
<TextView
android:id="@+id/text_to_replace"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="replace me"/>
</layout>
...and that I have two different ViewModels (FirstLayoutViewModel and SecondLayoutViewModel, each with a different String property). I want to use Data Binding to bind each ViewModel's string property to the text_to_replace
element in reusable_layout.xml
.
How can I do this? Normally, I would declare a variable in a <data>
tag and assign the type to the appropriate ViewModel but how can I do this if the layout (reusable_layout.xml
) is being used multiple times? How will it know which ViewModel type to use?
In this example, I could just use a different TextView for the first_layout and second_layout layout instead of importing a layout but in my real project, the layout I want to reuse is much more complicated and it makes sense to reuse.
Any help would be great. Thanks!
You're saying you just need a to display a String
so instead of passing a FirstLayoutViewModel
and SecondLayoutViewModel
, you should pass the String
to your reusable_layout
.
<layout>
<data>
<variable name="myText" type="String> />
</data>
<TextView
android:id="@+id/text_to_replace"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{myText}"/>
</layout>
More details: how to pass data in includes
class MyViewModel1 : ViewModel {
private val _myLiveData = MutableLiveData<String>()
val myLiveData: LiveData<String>
get() = _myLiveData
init {
//Assign MyLiveData
}
}
class MyViewModel2 : ViewModel {
private val _mySecondLiveData = MutableLiveData<String>()
val mySecondLiveData: LiveData<String>
get() = _mySecondLiveData
init {
//Assign MyLiveData
}
}
FirstLayout:
<layout>
<data>
<variable name="viewModel" type="MyViewModel1"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/title_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First layout title"/>
<include
layout="@layout/reusable_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:myText="@{viewModel.myLiveData}"
/>
</LinearLayout>
</layout>
SecondLayout:
<layout>
<data>
<variable name="viewModel" type="MyViewModel2"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/title_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First layout title"/>
<include
layout="@layout/reusable_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:myText="@{viewModel.mySecondLiveData}"
/>
</LinearLayout>
</layout>