なんか前のやり方でできなくなってたので
環境
- Android Studio 4.1
- Kotlin
- Mac
結論
ライブラリ
plugins {
id 'kotlin-android-extensions'
}
dependencies {
// ViewModel
implementation "androidx.activity:activity-ktx:1.1.0" // Activityから使う時
implementation "androidx.fragment:fragment-ktx:1.2.5" // Fragmentから使う時
}
バージョンは
Activity - AndroidDeveloper
Fragment - AndroidDeveloper
から安定版を使用
いやなんでこれデフォルトで入ってないんだよ
extensions
はsynthetic
でfindViewByIdの代わりにする時のやつ
Kotlin Android Extensionsを試してみた - Qiita
今まではデフォルトで入ってたのに4.1で消えた
今後はViewBindingが推奨らしいのでそっちにしましょう
この記事は修正がめんどくさいのでそのままですが
Activity
val viewModel: SampleViewModel by viewModels()
Activityから呼ぶ時はby viewModels()
Fragment
val viewModel: SampleViewModel by activityViewModels() // Activityと同じViewModel使う時はこっち
val viewModel: SampleViewModel by viewModels() // こっちだと新しいインスタンスを作成っぽい
Fragmentから呼ぶ時は二通り、好きな方を使う
Activityと同じインスタンスを使いたければby activityViewModels()
ViewModel
class SampleViewModel: ViewModel() {
// 中身
}
ViewModelは変わらず、ViewModel()を継承するだけ
コード全文
とにかく簡単にViewModelまとめリスペクトで、ActivityとViewModelそれぞれの変数からtextViewに表示してボタンを押したら値を+1するサンプル
ViewModelって何?の説明もリスペクト元の記事に短くまとまってるのでどうぞ
Github
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/textViewModel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewModel" />
</androidx.constraintlayout.widget.ConstraintLayout>
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels // by viewModels()用
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModel: SampleViewModel by viewModels() // ViewModelのインスタンスを作成
var activityVariable: Int = 0 // Activityに保存する変数
// 画面作成時に表示
textActivity.text = activityVariable.toString() // Activityの変数を表示
textViewModel.text = viewModel.viewModelVariable.toString() // ViewModelの変数を表示
// ボタンを押したら+1する
button.setOnClickListener {
// 変数の値を+1
activityVariable++
viewModel.viewModelVariable++
// 表示
textActivity.text = activityVariable.toString()
textViewModel.text = viewModel.viewModelVariable.toString()
}
}
}
import androidx.lifecycle.ViewModel
class SampleViewModel: ViewModel() {
var viewModelVariable: Int = 0 // ViewModelに保存する変数
}
参考にした記事
Android Jetpack(AndroidXライブラリ)の最近の更新
[Android]lifecycleライブラリ2.2.0からViewModelProviders.ofが非推奨になっちゃった件