在Kotlin+Compose+Navigator的Android应用中用SharedPreferences存表单数据
解决你的核心问题:
你遇到的Unresolved reference: getSharedPreferences错误,是因为Compose导航中的"页面"是可组合函数(@Composable),不是传统的Android Fragment,所以不能直接调用getSharedPreferences,必须通过Context获取。下面给你三种实用方案,从易到难:
方案1:直接在可组合函数中通过LocalContext获取
这是最快捷的方式,适合新手快速上手:
import android.content.Context import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext @Composable fun FormScreen() { // 1. 获取当前Context val context = LocalContext.current // 2. 初始化SharedPreferences(用remember缓存,避免每次重组重新创建) val sharedPreferences = remember { context.getSharedPreferences("MY_APP_PREFS", Context.MODE_PRIVATE) } var inputText by remember { mutableStateOf("") } Column { TextField(value = inputText, onValueChange = { inputText = it }) Button(onClick = { // 3. 存储数据到SharedPreferences sharedPreferences.edit { putString("user_input", inputText) } // 或者用传统写法: // sharedPreferences.edit().putString("user_input", inputText).apply() }) { Text(text = "保存数据") } } }
方案2:封装全局工具类(推荐,代码更整洁)
把SharedPreferences的操作封装成单例类,全局可调用,不用重复写获取逻辑:
- 创建工具类:
import android.content.Context import android.content.SharedPreferences object PrefsManager { private lateinit var prefs: SharedPreferences private const val PREFS_NAME = "APP_FORM_PREFS" // 在App启动时初始化(比如MainActivity的onCreate中) fun init(context: Context) { prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) } // 存储字符串 fun putString(key: String, value: String) { prefs.edit().putString(key, value).apply() } // 获取字符串(默认空字符串) fun getString(key: String, defaultValue: String = ""): String { return prefs.getString(key, defaultValue) ?: defaultValue } // 按需添加其他类型的方法:putInt、getInt、putBoolean等 }
- 在MainActivity中初始化:
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化工具类 PrefsManager.init(this) setContent { // 你的导航代码 MyAppNavHost() } } }
- 在任何可组合函数中直接使用:
import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @Composable fun FormScreen() { var inputText by remember { mutableStateOf("") } Column { TextField(value = inputText, onValueChange = { inputText = it }) Button(onClick = { // 直接调用工具类存储 PrefsManager.putString("user_input", inputText) }) { Text(text = "保存数据") } } }
方案3:结合ViewModel管理(符合MVVM架构)
如果你的项目已经在用ViewModel,可以把SharedPreferences的操作放到ViewModel中,让UI层和数据层解耦:
- 先按方案2创建好
PrefsManager - 创建ViewModel:
import androidx.lifecycle.ViewModel class FormViewModel(private val prefsManager: PrefsManager) : ViewModel() { fun saveFormInput(key: String, value: String) { prefsManager.putString(key, value) } fun getFormInput(key: String): String { return prefsManager.getString(key) } }
- 在可组合函数中获取ViewModel并使用:
import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.ViewModelProvider @Composable fun FormScreen() { val viewModel: FormViewModel = viewModel( factory = object : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return FormViewModel(PrefsManager) as T } } ) var inputText by remember { mutableStateOf("") } Column { TextField(value = inputText, onValueChange = { inputText = it }) Button(onClick = { viewModel.saveFormInput("user_input", inputText) }) { Text(text = "保存数据") } } }
关键注意事项:
- 不要在可组合函数的顶层初始化SharedPreferences,必须放在可组合函数内部,并用
remember缓存,避免每次重组重复创建实例。 - 存储数据时用
apply()而非commit():apply()是异步提交,不会阻塞主线程,更适合UI操作;commit()是同步的,可能导致卡顿。
内容的提问来源于stack exchange,提问作者Aletta Karsies van Eeden
相关产品推荐
相关产品推荐

