Подумав, я придумал простой, но не проверяющий метод, используя тип класса в сочетании с обобщениями для полной функциональности.Я полагаю, что это решит ваши проблемы с возможностью повторного использования и удаления избыточных прослушивателей так, как вы надеялись.
class SharedViewModel <T> (val listType: Class<T>) : ViewModel() {
var data: MutableLiveData<ArrayList<T>> = MutableLiveData()
fun setData(anyData: ArrayList<T>) {
data.value = anyData
}
inline fun <reified K> isOfInternalType(checkType: Class<K>): Boolean = checkType.typeName == listType.typeName
}
Установка данных массива через viewModel
class Xclass
var xArray = arrayListOf<Xclass>()
val viewModel = (activity as MainActivity).getViewModelInstance()
if (viewModel.isOfInternalType(Xclass::class.java) {
viewModel.setData(Xclass)
}
Основная активность
class Xclass
private var xArray = arrayListOf<Xclass>()
onCreate()
...
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
viewModel.getAnyData.observe(this, Observer { data: ArrayList<out Any?> ->
if (viewModel.isOfInternalType(Xclass::class.java) {
xArray.addAll(it)
}
})
Другие примеры использования
// Examples of use cases outside of initial question
class ViewOne: SharedView<ClassOne>(ClassOne::class.java)
val testClass = ViewOne()
ViewOne().isOfInternalType(ClassTwo::class.java) // returns false
ViewOne().isOfInternalType(testClass::class.java) // Error: Cannot use captured type as reified parameter
ViewOne().isOfInternalType(ClassOne::class.java) // returns true
ViewOne().isOfInternalType(ClassOne().javaClass) // returns true
testClass.isOfInternalType(ClassOne::class.java) // returns true
То, что я сделал, - это создание экземпляра listType представления, ожидаемого при создании экземпляра.Это необходимо сделать, потому что классы не поддерживают преобразование типов, как встроенная функция.В этой реализации предполагается, что каждый View будет иметь статический listType ... Это можно изменить, чтобы он выглядел следующим образом:
class SharedViewModel(listType: Class<*>) : ViewModel() {
var listType: Class<*> = listType
private set(value) {
field = value
}
fun setData(anyData: ArrayList<*>) {
data.value = anyData
}
fun updateListType(newType: Class<*>) {
listType = newType
}
inline fun <reified K> isOfInternalType(checkType: Class<K>): Boolean =
checkType.typeName == listType.typeName
}
Тип переменной SharedViewModel Примеры
class ViewOne: SharedView(ClassOne::class.java)
val testClass = ViewOne()
testClass.isOfInternalType(ClassOne::class.java) // returns true
testClass.updateListType(ClassTwo::class.java)
testClass.isOfInternalType(ClassOne::class.java) // returns false now
testClass.isOfInternalType(ClassTwo::class.java) // returns true now
С помощью этой реализации переменнойнабирая текст, вы захотите связать свой isOfInternalType
с setData
, чтобы обеспечить безопасность типов
. Этого должно быть достаточно для того, чтобы вы могли достичь своих архитектурных целей в этом проекте.я знаю, если я что-то неправильно понял и могу помочь в дальнейшем.