I want to use a smaller layout with its own view model a few times within my main layout like so (using LinearLayout for simplicity):
sub_layout.xml
<layout>
<data>
<variable
name="subVm"
type="...SubViewModel" />
</data>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/sub_tv_value"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="@{subVm.valueString}" />
<Button
android:id="@+id/sub_btn_do_something"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{subVm.doSomethingString}" />
</LinearLayout>
</layout>
main_activity.xml
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/sub_includable_view"
android:id="@+id/main_v_0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="@layout/sub_includable_view"
android:id="@+id/main_v_1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
SubViewModel.kt
class SubViewModelFactory(private val number: Int) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SubViewModel::class.java)){
return SubViewModel(number) as T
}
throw IllegalArgumentException("Unknown SubViewModel class")
}
}
class SubViewModel(value: Int) : ViewModel() {
val valueString: String = value.toString()
val doSomethingString: String = "Do Something $value"
}
However, when I set the view model of those individual layouts, each view appears to be referencing the same SubViewModel instance.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val subVm0: SubViewModel by viewModels() {
SubViewModelFactory(0)
}
private val subVm1: SubViewModel by viewModels() {
SubViewModelFactory(1)
}
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.mainV0.subVm = subVm0
binding.mainV1.subVm = subVm1
}
}
Results:
Is it possible to reuse a layout multiple times within a layout, and have each of those layouts have a different instance of the SubViewModel class? Or will they always reference the same instance this way?
We could just implement the desired functionality in the main_activity.xml with one MainViewModel but I'm curious if this way of code-reuse is possible. Any ideas? Thanks!
