SharedPreferences - Android Studio - Compose

How to use SharedPreferences using Android Studio with Jetpack Compose

SharedPreferences in Android Studio is one of the simplest and most commonly used ways to store small amounts of data on Android devices. It allows you to save values in the form of key–value pairs, making it ideal for storing lightweight and persistent data such as user settings, app preferences, login states, theme choices, and more.

SharedPreferences supports saving the following data types: String, int, boolean, long, float, and Set<String>. Because it is lightweight and fast, it is recommended when you need to store a small collection of simple key-value data.

Using SharedPreferences, you can easily addupdate, and remove stored values without needing complex storage solutions like databases.

To access SharedPreferences in Android, you can use any of the following APIs depending on your requirement:

  • getPreferences() – Accesses preferences that belong to a single Activity. Useful when the data is specific to that Activity only.

  • getSharedPreferences() – Accesses application-wide shared preferences from any Activity or Context. Best for global values used across the app.

  • getDefaultSharedPreferences() – Accesses the default preference file used by Android’s PreferenceManager, commonly used when working with the settings screen or Android's preference framework.

SharedPreferences offers a simple and efficient way to store persistent data, making it a must-know feature for every Android developer.

>> Check For Java

Code:

MainActivity.kt

package com.technifysoft.myapplication

import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
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.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.technifysoft.myapplication.ui.theme.MyApplicationTheme
import androidx.core.content.edit

class MainActivityCompose : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainUi()
        }
    }
}

@Composable
fun MainUi() {
    val context = LocalContext.current

    // It's better to initialize SharedPreferences once and reuse the instance.
    // `remember` will keep the instance across recompositions.
    val sharedPreferences = remember {
        context.getSharedPreferences("USER_INFO_SP", Context.MODE_PRIVATE)
    }

    // Correct: Initialize state directly inside `remember` to avoid re-reading on every recomposition.
    // This is the most efficient way for one-time initialization.
    var name by remember {
        mutableStateOf(sharedPreferences.getString("NAME", "") ?: "")
    }
    var age by remember {
        mutableIntStateOf(sharedPreferences.getInt("AGE", 0))
    }
    var email by remember {
        mutableStateOf(sharedPreferences.getString("EMAIL", "") ?: "")
    }
    var password by remember {
        mutableStateOf(sharedPreferences.getString("PASSWORD", "") ?: "")
    }
    var isRemembered by remember {
        mutableStateOf(sharedPreferences.getBoolean("REMEMBER", false))
    }

    var passwordVisible by remember { mutableStateOf(false) }


    Scaffold(
        modifier = Modifier.fillMaxSize()
    ) { paddingValues ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(paddingValues)
                .padding(20.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(16.dp),
                text = "Shared Preferences",
                textAlign = TextAlign.Center,
            )

            OutlinedTextField(
                modifier = Modifier.fillMaxWidth(),
                value = name, onValueChange = { name = it },
                placeholder = { Text(text = "Name") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
            )

            Spacer(modifier = Modifier.height(10.dp))

            OutlinedTextField(
                modifier = Modifier.fillMaxWidth(),
                value = if (age == 0) "" else age.toString(),
                onValueChange = {
                    // Safely convert to Int, default to 0 if input is invalid or empty
                    age = it.toIntOrNull() ?: 0
                },
                placeholder = { Text(text = "Age") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
            )

            Spacer(modifier = Modifier.height(10.dp))

            OutlinedTextField(
                modifier = Modifier.fillMaxWidth(),
                value = email, onValueChange = { email = it },
                placeholder = { Text(text = "Email") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)
            )

            Spacer(modifier = Modifier.height(10.dp))

            OutlinedTextField(
                modifier = Modifier.fillMaxWidth(),
                value = password, onValueChange = { password = it },
                placeholder = { Text(text = "Password") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
                trailingIcon = {
                    val image =
                        if (passwordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff
                    val description = if (passwordVisible) "Hide password" else "Show password"

                    IconButton(onClick = { passwordVisible = !passwordVisible }) {
                        Icon(
                            imageVector = image,
                            contentDescription = description
                        )
                    }
                }
            )

            Spacer(modifier = Modifier.height(10.dp))

            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Checkbox(checked = isRemembered, onCheckedChange = {
                    isRemembered = it
                })
                Text(text = "Remember Me")
            }

            Button(
                modifier = Modifier,
                onClick = {
                    //get data from views
                    if (isRemembered) {
                        isRemembered = true
                        // Save data to shared preferences
                        sharedPreferences.edit().apply {
                            putString("NAME", name)
                            putInt("AGE", age)
                            putString("EMAIL", email)
                            putString("PASSWORD", password)
                            putBoolean("REMEMBER", true)
                            apply()
                        }
                        Toast.makeText(context, "Info is remembered...", Toast.LENGTH_SHORT).show()
                    } else {
                        // Don't save | remove data from shared preferences
                        sharedPreferences.edit { clear() }
                        Toast.makeText(context, "Info is not remembered...", Toast.LENGTH_SHORT)
                            .show()
                    }
                }) {
                Text(text = "Save")
            }
        }

    }
}


/**
 * GreetingPreview is a composable function for previewing the MainUI in Android Studio.
 * It is annotated with @Preview to enable live preview.
 *
 */
@Preview(showBackground = true)
@Composable
private fun GreetingPreview() {
    MyApplicationTheme {
        MainUi()
    }
}

Screenshots:

Comments

Popular posts from this blog

Picture In Picture - Android Studio - Kotlin

Manage External Storage Permission - Android Studio - Kotlin

SeekBar with Customization | Android Studio | Java