前人未踏の領域へ Androidアプリ開発編

Androidアプリ開発に関する調査メモ置き場。古い記事にはアプリ以外も含まれます。

Android:SavedStateHandleでFragmentの引数をViewModelで受け取れるようになってた

追記

HiltViewModelを使うとActivity起動時に使われるIntentパラメータの値も下記記事と同様に ViewModelのSavedStateHandleにセットされていることを確認。

内容

Fragment 1.2.0 以降で利用可能になった SavedStateHandle を試しに書いてみたら いつもFragmentからrequireArguments()で取得してた内容が savedStateHandleの中に入ってたという話。

コード

コンストラクタに引数を追加する。これだけ。ViewModel名はお好みで

class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() { ... }

Fragmentはこんな感じ。 newInstance(userId)でMainFragmentを引数付きで起動するイメージ。

class MainFragment : Fragment() {
    val vm: SavedStateViewModel by viewModels()

    companion object {
         fun newInstance(val userId: Int) : MainFragment =
                MainFragment().apply {
                     arguments = Bundle().apply {
                            putInt("userId", userId)
                     }
                }
    }
}

ViewModel側でおもむろに使用する。getLiveData()を使えばLiveDataとして使うこともできる。

class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() { 
    init {
        val userId: Int = state.get(userId)!!
    }
 }

これで一覧をリクエストする処理なんかをViewModel側で完結して書けるようになったと思う。

感想

Hiltを使っていても関係なく、特に特別な記述も必要なかった。
本当はSavedStateHandleを調べようとし始めたばかりだったんだけど、セットもしてないのに値が入っててびっくりしたのでとりあえず。
Fragmentに渡ってきた引数をViewModelにどう渡すかで試行錯誤してたのでこれは助かる。
もうちょっと色々できると思うので引き続き調べてみよう。

参考

developer.android.com