Получение общего класса от Kotlin Generic - PullRequest
0 голосов
/ 04 июня 2018

У меня есть следующая подпись класса:

abstract class BaseActivity<E : ViewModel> : AppCompatActivity() {

    protected lateinit var viewModel: E

}

Теперь я хочу инициализировать мою viewModel универсальным способом, используя ViewModelProvider, поэтому:

   viewModel = ViewModelProviders.of(this, viewModelFactory)
            .get(MyViewModel::class)

Учитывая, что класс MyViewModel будетв обобщенном типе я бы сказал, что это потенциально может быть абстрагировано в BaseActivity, поэтому мне не нужно делать это для каждого расширяющего его действия.

Я пытался использовать:

inline fun <reified E : ViewModel> getViewModelClass() = E::class.java

Но тогда при выполнении:

viewModel = ViewModelProviders.of(this, viewModelFactory)
            .get(getViewModelClass())

Я получаю Cannot use E as reified type paramter. Use class instead

Есть ли решение для этого?

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

E в BaseActivity не может быть reified, поэтому вы не можете передать его никаким методам, которые принимают reified E.

Лучшим вариантом может быть просто принятьclass в качестве параметра конструктора.

abstract class BaseActivity<E : ViewModel>(private val modelClass: Class<E>) : AppCompatActivity() {

    protected lateinit var viewModel: E

    ... viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(modelClass)
}

Если BaseActivity не является абстрактным, вы можете добавить фабричный метод:

// outside BaseActivity class itself
fun <reified E : BaseModel> BaseActivity() = BaseActivity(E::class.java)

, но это не поможет при его расширении.

0 голосов
/ 04 июня 2018

Вы можете сделать это следующим образом:

abstract class BaseActivity<E : ViewModel> : AppCompatActivity() {

protected lateinit var viewModel: E

abstract fun getViewModel():E

override fun onCreate(savedInstanceState: Bundle?){
    super.onCreate(savedInstanceState)
    viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(getViewModel())
}

}

Теперь вы можете расширить любой класс из BaseActivity и переопределить функцию getViewModel (), возвращая соответствующий класс ViewModel.

Надеюсь, этопомогает.

РЕДАКТИРОВАТЬ

Попробуйте это один раз:

 inline fun <reified E> getViewModelClass(): Class<E> {
    return E::class.java
}

и используйте его так:

viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(getViewModelClass())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...