3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ViewModelProviderクラスを定義せずにViewModelを生成する

Last updated at Posted at 2020-03-30

はじめに

つい最近ViewModelを触り始めたのですが、当初は律儀にViewModelProvider(s)を使っていました。
しかし、fragment-ktxを使うことでかなり簡素にViewModelを生成出来たので自分用に纏めておきます。

実装

jvmTargetを1.8に指定し、lifecycle-viewmodel-ktxfragment-ktxを追加する。

build.gradle

android {
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
    implementation "androidx.fragment:fragment-ktx:1.2.3"
}

引数なしの場合

まずは引数なしのViewModelから。
とりあえず引数なしのViewModelを定義する。
initとhelloメソッド呼び出しのタイミングでそれぞれログを出力させる。

MainViewModle.kt
class MainViewModel : ViewModel() {
    init {
        Log.d("MainViewModel", "init")
    }

    fun hello() {
        Log.d("MainViewModel", "hello")
    }
}

1行サクッと書くだけでViewModelが取得できる。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels() // ← ここ!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.hello()
    }
}

initとhelloメソッド呼び出しのタイミングでそれぞれログが出力されているのがわかる。

log
2020-03-30 22:48:02.199 3963-3963/com.masaibar.viewmodelsample D/MainViewModel: init
2020-03-30 22:48:02.199 3963-3963/com.masaibar.viewmodelsample D/MainViewModel: hello

引数ありの場合

続いて引数ありの場合、先程のViewModelのコンストラクタをuserIdという引数を受け付けるように変更した。

MainViewModle.kt
class MainViewModel(
    private val userId: String
) : ViewModel() {
    init {
        Log.d("MainViewModel", "init, userId: $userId")
    }

    fun hello() {
        Log.d("MainViewModel", "hello, userId: $userId")
    }
}

今度は先程のように1行だけサクッとという訳にはいかないが
それでもViewModelProviderクラスを定義しなくてもこのように書くことが出来る。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels {
        object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                @Suppress("UNCHECKED_CAST")
                return MainViewModel("masaibar") as T
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.hello()
    }
}

initとhelloメソッド呼び出しのタイミングでそれぞれログが出力されuserIdが渡っていることが確認できる。

log
2020-03-30 22:58:52.525 4979-4979/? D/MainViewModel: init, userId: masaibar
2020-03-30 22:58:52.525 4979-4979/? D/MainViewModel: hello, userId: masaibar

おわりに

Googleにはもう少しこれを推していって欲しいです。

参考:https://developer.android.com/kotlin/ktx?hl=ja#fragment

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?