Как использовать ViewModelProviders в Котлине

Я новичок в Kotlin. Пожалуйста, помогите мне, как использовать ViewModelProviders.of(this) в Kotlin.

Мой код в java

 mFavViewModel = ViewModelProviders.of(this).get(FavouritesViewModel.class);

Я не могу найти класс ViewModelProviders в kotlin, пробовал автоматическое преобразование, но он показывает ошибки. Спасибо.

Вот мой класс DataModel

class FavoritesDataViewModel:ViewModel{
    private var mFavHelper: DatabaseHelper
    private lateinit var mfav:ArrayList<Favorites>
     constructor(application: Application) {
        mFavHelper = DatabaseHelper(application)
    }
    fun getListFav():List<Favorites>{
        if (mfav==null){
            mfav =  arrayListOf<Favorites>()
            createDummyList()
            loadFav()
        }
        val clonedFavs = arrayListOf<Favorites>()
        for (i in 0 until mfav.size) {
            clonedFavs.add(Favorites(mfav.get(i)))
        }
        return clonedFavs
    }
    fun createDummyList(){
        addFav("https://www.journaldev.com", Date().getTime())
        addFav("https://www.medium.com", Date().getTime())
        addFav("https://www.reddit.com", Date().getTime())
        addFav("https://www.github.com", Date().getTime())
        addFav("https://www.hackerrank.com", Date().getTime())
        addFav("https://www.developers.android.com", Date().getTime())

    }
    fun addFav(url:String,date:Long):Favorites{
        val db:SQLiteDatabase = this.mFavHelper.getWritableDatabase();
        val values: ContentValues = ContentValues();
        values.put(DbSettings.DbEntry.COL_FAV_DATE,date)
        values.put(DbSettings.DbEntry.COL_FAV_URL,url)
        val id:Long = db.insertWithOnConflict(DbSettings.DbEntry.TABLE,
            null,
            values,SQLiteDatabase.CONFLICT_REPLACE)
        db.close()
        val fav:Favorites = Favorites(id,url,date)
        mfav.add(fav)
        return Favorites(fav)
    }
    fun loadFav(){
        mfav.clear()
        val db:SQLiteDatabase = mFavHelper.readableDatabase
        val cursor:Cursor = db.query(DbSettings.DbEntry.TABLE,
             arrayOf(
                DbSettings.DbEntry._ID,
                DbSettings.DbEntry.COL_FAV_URL,
                DbSettings.DbEntry.COL_FAV_DATE
             ),
            null, null, null, null, null);
        while (cursor.moveToNext()){
            val idxID:Int = cursor.getColumnIndex(DbSettings.DbEntry._ID)
            val idxURL:Int = cursor.getColumnIndex(DbSettings.DbEntry.COL_FAV_URL)
            val idxDate:Int = cursor.getColumnIndex(DbSettings.DbEntry.COL_FAV_DATE)
            mfav.add(Favorites(cursor.getLong(idxID),cursor.getString(idxURL),cursor.getLong(idxDate)))
        }
        cursor.close()
        db.close()
    }

}

попробовал со следующей строкой кода

var mFavViewModel = ViewModelProviders.of(activity).get(FavouritesViewModel::class.java)
implementation 'android.arch.lifecycle:extensions:1.1.1'

это дает ошибку:

  Caused by: java.lang.RuntimeException: Cannot create an instance of class com.nearex.mykotlinsample.viewmodel.FavoritesDataViewModel
            at android.arch.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:153)
            at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:210)
            at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134)
            at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102)
            at com.nearex.mykotlinsample.view.MainActivity.onCreate(MainActivity.kt:29)

person Uma Achanta    schedule 19.12.2018    source источник
comment
Ознакомьтесь с официальным руководством по стилю именования Kotlin developer.android.com/kotlin/style-guide. в котором говорится, что Специальные префиксы или суффиксы, подобные тем, что показаны в примерах name_, mName, s_name и kName, не используются, кроме как в случае резервных свойств (которые имеют префикс от _)   -  person EpicPandaForce    schedule 20.12.2018
comment
@EpicPandaForce Спасибо за предложение. Обязательно последует за этим.   -  person Uma Achanta    schedule 20.12.2018


Ответы (3)


Для Java

Для версий до AndroidX

implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation "android.arch.lifecycle:viewmodel:1.1.0"

Для AndroidX

implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"

В последней версии ViewModel можно объявить следующим образом:

MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class);

Для Котлина

Для версий до AndroidX

implementation 'android.arch.lifecycle:extensions-ktx:1.1.1'
implementation "android.arch.lifecycle:viewmodel-ktx:1.1.1"

Для Android

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"

Объявление ViewModel

val model = ViewModelProvider(activity)[MyViewModel::class.java]

См. ссылку ниже для получения последней версии AndroidX

Примечание. Для версий до AndroidX версия зависимостей не будет обновлена.

person Mittal Varsani    schedule 19.12.2018
comment
Просто чтобы расширить этот ответ, убедитесь, что все ваши зависимости компонентов арки имеют одинаковый формат. То есть: не смешивать зависимости android.arch и androidx. Имейте в виду, что если вы хотите использовать Navigation Component, на момент написания этого комментария он доступен только как зависимость android.arch. - person Eric Martori; 19.12.2018
comment
@Mittal Varsani Я отредактировал свой вопрос, пожалуйста, проверьте и помогите мне - person Uma Achanta; 19.12.2018
comment
просто сделайте свой конструктор общедоступным и попробуйте @UmaAchanta - person Mittal Varsani; 19.12.2018

Попробуйте ниже

var mFavViewModel = ViewModelProviders.of(activity).get(FavouritesViewModel::class.java)
person Mehul Kabaria    schedule 19.12.2018
comment
получение ошибки в ViewModelProviders. Это не импорт - person Uma Achanta; 19.12.2018
comment
ViewModelProviders теперь устарел. Вы должны использовать ответ Миттал в Котлине. - person The_Martian; 14.10.2020

Предполагается, что kotlin используется — класс ViewModelProviders устарел, вместо него можно использовать ViewModelProvider. Чтобы использовать это, нужно добавить зависимость в app build.gradle примерно так:

 implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

Создайте класс модели представления -

class MyViewModel: ViewModel(){
}

Этот же объект класса можно найти из фрагмента — onCreateView. Например -

class MyFragment: Fragment(){
    ...
    private lateint var myViewModel: MyViewModel
    ...
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
         ...
         myViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
         ...

     }

}
person Pravind Kumar    schedule 26.04.2020