如何在 Kotlin 中使用 ViewModelProviders
Posted
技术标签:
【中文标题】如何在 Kotlin 中使用 ViewModelProviders【英文标题】:How to use ViewModelProviders in Kotlin 【发布时间】:2019-05-19 16:30:45 【问题描述】:我是 Kotlin 的新手,请帮助我.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 命名风格指南 developer.android.com/kotlin/style-guide,其中说“特殊前缀或后缀,如示例 name_、mName
、s_name 和 kName 中所见,是不使用,除了后备属性(前缀为_
)”
@EpicPandaForce 感谢您的建议。一定会遵循这个。
【参考方案1】:
对于 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 dependency version参考下面的链接
注意:对于pre-AndroidX,依赖版本不会更新
【讨论】:
只是为了扩展这个答案,请确保您所有的 Arch 组件依赖项都采用相同的格式。即:不混合android.arch
和androidx
依赖项。请记住,如果您想使用Navigation Component
,目前它仅作为android.arch
依赖项提供
@Mittal Varsani 我已经编辑了我的问题,请检查并帮助我
公开你的构造函数并尝试@UmaAchanta【参考方案2】:
它假定 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)
...
【讨论】:
【参考方案3】:下面试试
var mFavViewModel = ViewModelProviders.of(activity).get(FavouritesViewModel::class.java)
【讨论】:
在 ViewModelProviders 处出现错误。它没有导入 ViewModelProviders 现已弃用。您应该在 Kotlin 中使用 Mittal 的答案。以上是关于如何在 Kotlin 中使用 ViewModelProviders的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kotlin Multiplatform(纯 kotlin)中进行延迟
如何在 Kotlin/Multiplatform 项目中使用 .klib 库