Memo

メモ > 技術 > IDE: AndroidStudio > アプリの作成(Jetpack Compose / データの保存)

■アプリの作成(Jetpack Compose / データの保存)
※今は「SharedPreferences」ではなく、「DataStore」を使うことが推奨されているらしい ※未検中 アプリ アーキテクチャ: データレイヤー - DataStore - デベロッパー向け Android | Android デベロッパー | Android Developers https://developer.android.com/topic/libraries/architecture/datastore?hl=ja DataStoreを試してみる https://zenn.dev/slowhand/articles/455aa5cd244e90 【Kotlin/Android Studio】DataStoreの使い方!データの保存と取得方法 https://tech.amefure.com/android-datastore build.gradle の dependencies 内に以下を追加する
implementation "androidx.datastore:datastore-preferences:1.0.0"
追加したら「Sync Now」をクリックする プログラムを記述するファイルの最上位で以下を呼び出すことにより、シングルトンで dataStore にアクセスできるようになる
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
なお、上記のコードでインポートすべきライブラリは以下のとおり
import android.content.Context import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.preferencesDataStore
特にPreferencesのインポート時、他の物をインポートしてしまうと、以下のエラーになるので注意
Property delegate must have a 'getValue(Context, KProperty<*>)' method. None of the following functions is suitable: public abstract operator fun getValue(thisRef: Context, property: KProperty<*>): DataStore<Preferences> defined in kotlin.properties.ReadOnlyProperty
flow.firstのインポート時も、インポートすべきライブラリは以下なので注意
import kotlinx.coroutines.flow.first
以下のとおり実装する
package com.example.helloworld import android.content.Context import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore import com.example.helloworld.ui.theme.HelloWorldTheme import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import java.io.IOException val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings") class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { HelloWorldTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { MainScreen() } } } } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun MainScreen() { val context = LocalContext.current var inputText by remember { mutableStateOf(TextFieldValue("")) } Column( modifier = Modifier .fillMaxSize() .padding(16.dp) ) { OutlinedTextField( value = inputText, onValueChange = { inputText = it }, modifier = Modifier.fillMaxWidth() ) Spacer(modifier = Modifier.height(16.dp)) Row { Button(onClick = { runBlocking(Dispatchers.IO) { putText(context, inputText.text) } }) { Text("保存") } Spacer(modifier = Modifier.width(16.dp)) Button(onClick = { runBlocking(Dispatchers.IO) { inputText = TextFieldValue(getText(context)) } }) { Text("復元") } } } } suspend fun putText(context: Context, text: String) { try { context.dataStore.edit { settings -> settings[stringPreferencesKey("text")] = text } } catch (e: IOException) { Log.d("putText", text) } } suspend fun getText(context: Context): String { var text = "" try { text = context.dataStore.data.first()[stringPreferencesKey("text")].toString() } catch (e: IOException) { Log.d("getText", text) } return text } @Preview(showSystemUi = true) @Composable fun MainScreenPreview() { MainScreen() }

Advertisement