You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Kotlin+Compose+Navigator的Android应用中用SharedPreferences存表单数据

在Compose + Navigator架构中使用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的操作封装成单例类,全局可调用,不用重复写获取逻辑:

  1. 创建工具类:
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等
}
  1. 在MainActivity中初始化:
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化工具类
        PrefsManager.init(this)
        setContent {
            // 你的导航代码
            MyAppNavHost()
        }
    }
}
  1. 在任何可组合函数中直接使用:
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层和数据层解耦:

  1. 先按方案2创建好PrefsManager
  2. 创建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)
    }
}
  1. 在可组合函数中获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:20:58