如何在Kotlin中使用ViewModelProviders

13

我是Kotlin的新手,请帮助我如何在Kotlin中使用ViewModelProviders.of(this)

我的Java代码为

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

我无法在 Kotlin 中找到 ViewModelProviders 类。尝试进行自动转换,但显示错误。

这是我的 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)

请仔细阅读官方的 Kotlin 命名风格指南,其中指出:“除了用于支持属性(以_作为前缀)的情况外,不使用特殊的前缀或后缀,例如在示例中看到的 name_、mName、s_name 和 kName”。 - EpicPandaForce
1
@EpicPandaForce 感谢您的建议。我一定会遵循它。 - Uma Achanta
3个回答

36

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);

Kotlin开发:

适用于AndroidX之前版本

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

安卓设备

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

ViewModel声明

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

请参考下面的链接获取最新的AndroidX依赖版本

注意: 对于pre-AndroidX,依赖版本将不会更新


1
为了扩展这个答案,请确保所有的架构组件依赖都是相同的格式。也就是说:不要混合使用 android.archandroidx 依赖项。请记住,如果您想使用 Navigation Component,在本评论时它只能作为一个 android.arch 依赖项使用。 - Eric Martori
@Mittal Varsani 我已经编辑了我的问题,请您检查并帮助我。 - Uma Achanta
只需将您的构造函数设置为公共,并尝试使用@UmaAchanta。 - Mittal Varsani

5

假设使用 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)
         ...

     }

}

2
尝试以下操作:
var mFavViewModel = ViewModelProviders.of(activity).get(FavouritesViewModel::class.java)

2
在ViewModelProviders处出现错误。它没有被导入。 - Uma Achanta
ViewModelProviders现在已经被弃用,您应该使用Kotlin中的Mittal答案。 - The_Martian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接