13

I am new bie to Kotlin, Please help me how to use ViewModelProviders.of(this) in Kotlin

My code in java is

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

I am not able to find ViewModelProviders class in kotlin tried auto convert but its showing errors. Thanks.

Here is my DataModel class

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()
    }

}

tried with following line of code

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

this is giving error:

  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)
Uma Achanta
  • 3,669
  • 4
  • 22
  • 49
  • Please read official Kotlin naming style guide https://developer.android.com/kotlin/style-guide which says "***Special prefixes or suffixes, like those seen in the examples name_, `mName`, s_name, and kName, are not used*** except in the case of backing properties (which is prefixed by `_`)" – EpicPandaForce Dec 20 '18 at 01:39
  • 1
    @EpicPandaForce Thanks for the suggestion. Will surely follow this. – Uma Achanta Dec 20 '18 at 05:45

3 Answers3

36

For Java

For pre-AndroidX

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

For AndroidX

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

In the latest version, ViewModel can be declared as below

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

For Kotlin

For pre-AndroidX

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

For Android

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

ViewModel declaration

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

Refer below link for the latest AndroidX dependency version

Note: For pre-AndroidX, the dependency version will not be updated

Mittal Varsani
  • 5,601
  • 2
  • 15
  • 27
  • 1
    Just to expand this answer, make sure all your arch components dependencies are in the same format. That is: not mixing `android.arch` and `androidx` dependencies. Keep in mind that if you want to use the `Navigation Component`, at the moment of this coment it is only available as an `android.arch` dependency – Eric Martori Dec 19 '18 at 09:04
  • @Mittal Varsani I have edited my question please check and help me – Uma Achanta Dec 19 '18 at 09:22
  • just make your constructor public and try @UmaAchanta – Mittal Varsani Dec 19 '18 at 09:59
5

Its assumed kotlin is in use - Class ViewModelProviders has been deprecated, instead ViewModelProvider can be used. To use this need to add a dependency in app build.gradle something like this -

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

Create a view model class -

class MyViewModel: ViewModel(){
}

The same class object can be find from fragment - onCreateView. For example -

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

     }

}
Pravind Kumar
  • 809
  • 1
  • 11
  • 10
2

Try with below

var mFavViewModel = ViewModelProviders.of(activity).get(FavouritesViewModel::class.java)
Mehul Kabaria
  • 6,404
  • 4
  • 25
  • 50