SharedPreferences¶
Cuando necesitamos almacenar una cantidad limitada de datos, es adecuado utilizar la clase SharedPreferences.
Este mecanismo se emplea habitualmente para guardar configuraciones simples de la aplicación, como por ejemplo:
- Preferencias visuales (colores, modo oscuro).
- Nivel actual en un juego.
- Valores iniciales de controles de entrada.
- Datos básicos del usuario, como un nombre.
Las SharedPreferences están diseñadas para almacenar pequeñas cantidades de información mediante el modelo clave–valor.
Debe tratarse siempre de información no sensible, ya que Android genera un archivo XML sin cifrar donde se almacenan estos datos.
Nota
Aunque hoy se recomienda DataStore para nuevos desarrollos, SharedPreferences sigue siendo muy útil a nivel formativo.
Objetivo del proyecto¶
La aplicación tendrá el siguiente comportamiento:
- Si no hay ningún nombre guardado, se solicitará al usuario que lo introduzca.
- Si ya existe un nombre almacenado, se mostrará un saludo junto a un botón para borrarlo.
- Al borrar el nombre, la aplicación vuelve al estado inicial.
Además, se introduce el patrón Singleton para centralizar el acceso a las preferencias.
Maquetación inicial¶
activity_main.xml¶
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<EditText
android:id="@+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Escribe tu nombre"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/btnSaveValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Guardar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/btnDeleteValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Borrar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Clase Prefs¶
class Prefs(context: Context) {
private val PREFS_NAME = "com.cursokotlin.sharedpreferences"
private val SHARED_NAME = "shared_name"
private val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
var name: String
get() = prefs.getString(SHARED_NAME, "") ?: ""
set(value) = prefs.edit().putString(SHARED_NAME, value).apply()
}
Singleton con Application¶
class SharedApp : Application() {
companion object {
lateinit var prefs: Prefs
}
override fun onCreate() {
super.onCreate()
prefs = Prefs(applicationContext)
}
}
Añadir en AndroidManifest.xml:
<application
android:name=".SharedApp"
... >
Lógica de la Activity¶
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
configView()
btnSaveValue.setOnClickListener {
SharedApp.prefs.name = etName.text.toString()
configView()
}
btnDeleteValue.setOnClickListener {
SharedApp.prefs.name = ""
configView()
}
}
fun showProfile() {
tvName.visibility = View.VISIBLE
tvName.text = "Hola ${SharedApp.prefs.name}"
btnDeleteValue.visibility = View.VISIBLE
etName.visibility = View.INVISIBLE
btnSaveValue.visibility = View.INVISIBLE
}
fun showGuest() {
tvName.visibility = View.INVISIBLE
btnDeleteValue.visibility = View.INVISIBLE
etName.visibility = View.VISIBLE
btnSaveValue.visibility = View.VISIBLE
}
fun configView() {
if (isSavedName()) showProfile() else showGuest()
}
fun isSavedName(): Boolean {
return SharedApp.prefs.name.isNotEmpty()
}
}
Actividad¶
- AC601. Realiza el ejemplo en Compose, realiza una investigación para poder replicarlo.