#android #layout #data-binding #include #viewmodel
Вопрос:
Я хочу несколько раз использовать меньший макет с собственной моделью представления в моем основном макете, например ( LinearLayout
для простоты):
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"
}
Однако, когда я устанавливаю модель представления этих отдельных макетов, кажется, что каждое представление ссылается на один и тот же SubViewModel
экземпляр.
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
}
}
Результаты:
Можно ли повторно использовать макет несколько раз в макете, и чтобы каждый из этих макетов имел другой экземпляр SubViewModel
класса? Или они всегда будут ссылаться на один и тот же экземпляр таким образом?
Мы могли бы просто реализовать желаемую функциональность в main_activity.xml
с одним MainViewModel
, но мне любопытно, возможен ли такой способ повторного использования кода. Есть какие-нибудь идеи? Спасибо!
Комментарии:
1. AFAIK, данная область (в данном случае ваша деятельность) может иметь только одну модель представления данного типа. Таким образом, вы
subVm0
создаете этот экземпляр иsubVm1
извлекаете существующий экземпляр. Вам нужно будет использовать разные области, например, чтобы каждая из них была во фрагменте, и выполнить сборку фрагментов.