Open In App

Android Jetpack Compose - Creating a Color Picker Using Material 3 Slider Component

Last Updated : 04 May, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

In this article, we'll explore how to create a color picker using Jetpack Compose, leveraging Material 3 Slider components. A color is essentially a combination of different amounts of red, green, blue, and alpha values, and we'll manage these values using sliders in our color picker UI. A sample video is given below to get an idea about what we are going to do in this article.

Prerequisites:

Before diving into the tutorial, make sure you have a

  1. Basic Understanding of Jetpack Compose,
  2. The latest version of Android Studio installed and
  3. A Jetpack Compose project setup.

Step by Step Implementation

Step 1: Create a new project

To create a new project in the Android Studio, please refer to How to Create a new Project in Android Studio with Jetpack Compose.

Step 2: Creating the Color Picker Composable

We'll create a composable function named ColorPicker to encapsulate our color picker UI. This function will include sliders for adjusting the RGBA values and will display the current color in a box and the ARGB hex code in a Text composable.

Kotlin
@Composable
fun ColorPicker() {
    // State variables for RGBA values
    val alpha = rememberSaveable { mutableFloatStateOf(1f) }
    val red = rememberSaveable { mutableFloatStateOf(0f) }
    val green = rememberSaveable { mutableFloatStateOf(0f) }
    val blue = rememberSaveable { mutableFloatStateOf(0f) }

    // Derived state for the color based on RGBA values
    val color by remember {
        derivedStateOf {
            Color(red.floatValue, green.floatValue, blue.floatValue, alpha.floatValue)
        }
    }

    // UI layout using Scaffold and Column
    Column(modifier = Modifier.padding(8.dp)) {
        // Display the current color in a Box with a MaterialTheme shape
        Row {
            Box(
                modifier = Modifier
                    .padding(10.dp, 0.dp)
                    .fillMaxWidth()
                    .height(80.dp)
                    .background(color, shape = MaterialTheme.shapes.large)
            )
        }

        // Sliders for adjusting RGBA values
        Column(
            modifier = Modifier.padding(12.dp),
            verticalArrangement = Arrangement.spacedBy(5.dp)
        ) {
            ColorSlider("A", alpha, color.copy(1f))
            ColorSlider("R", red, Color.Red)
            ColorSlider("G", green, Color.Green)
            ColorSlider("B", blue, Color.Blue)
        }

        // Add Hex code display
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 12.dp, vertical = 8.dp),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = color.toHexCode(),
                style = MaterialTheme.typography.bodyLarge
            )
        }

    }
}


Step 3: Creating the ColorSlider Composable

Next, we'll define a composable function named `ColorSlider` to create individual sliders for adjusting the RGBA values. This function will take a label, a mutable state for the slider value, and a color for the slider's active track.

Kotlin
/**
 * A composable function that creates a slider for adjusting a float value associated with a color.
 *
 * @param label The label to display alongside the slider.
 * @param valueState The mutable state holding the current value of the slider.
 * @param color The color used for the active track of the slider.
 */
@Composable
fun ColorSlider(
    label: String,
    valueState: MutableState<Float>,
    color: Color,
) {
    /**
     * Displays a slider for adjusting the given [valueState] associated with the provided [label].
     * The slider's active track color is set to [color].
     */
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(6.dp)
    ) {
        Text(text = label)
        Slider(
            value = valueState.value,
            onValueChange = valueState.component2(),
            colors = SliderDefaults.colors(
                activeTrackColor = color
            ),
            modifier = Modifier.weight(1f)
        )
        Text(
            text = valueState.value.toColorInt().toString(),
            modifier = Modifier.width(25.dp),
            textAlign = TextAlign.End,
            style = MaterialTheme.typography.bodySmall
        )
    }
}


Step 4: Adding Utility Functions

We'll also include an extension function `toColorInt()` to convert float values to integer color components.

Kotlin
/**
 * Converts a float value in the range [0, 1] to an integer color component in the range [0, 255].
 *
 * @return The integer representation of the color component.
 */
fun Float.toColorInt(): Int = (this * 255 + 0.5f).toInt()

// Convert Color to Hex Code
fun Color.toHexCode(): String {
    val a = (alpha * 255).toInt()
    val r = (red * 255).toInt()
    val g = (green * 255).toInt()
    val b = (blue * 255).toInt()
    return String.format("#%02X%02X%02X%02X", a, r, g, b)
}


Step 5: Entire code for MainActivity.kt

Here's the entire code for MainActivity.kt. We can use the ColorPicker Composable in the MainActivity or other composables.

MainActivity.kt:

Kotlin
package com.geeksforgeeks.demo

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.*

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                ColorPicker()
            }
        }
    }
}

@Composable
fun ColorPicker() {
    // State variables for RGBA values
    val alpha = rememberSaveable { mutableFloatStateOf(1f) }
    val red = rememberSaveable { mutableFloatStateOf(0f) }
    val green = rememberSaveable { mutableFloatStateOf(0f) }
    val blue = rememberSaveable { mutableFloatStateOf(0f) }

    // Derived state for the color based on RGBA values
    val color by remember {
        derivedStateOf {
            Color(red.floatValue, green.floatValue, blue.floatValue, alpha.floatValue)
        }
    }

    // UI layout using Scaffold and Column
    Column(modifier = Modifier.padding(8.dp)) {
        // Display the current color in a Box with a MaterialTheme shape
        Row {
            Box(
                modifier = Modifier
                    .padding(10.dp, 0.dp)
                    .fillMaxWidth()
                    .height(80.dp)
                    .background(color, shape = MaterialTheme.shapes.large)
            )
        }

        // Sliders for adjusting RGBA values
        Column(
            modifier = Modifier.padding(12.dp),
            verticalArrangement = Arrangement.spacedBy(5.dp)
        ) {
            ColorSlider("A", alpha, color.copy(1f))
            ColorSlider("R", red, Color.Red)
            ColorSlider("G", green, Color.Green)
            ColorSlider("B", blue, Color.Blue)
        }

        // Add Hex code display
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 12.dp, vertical = 8.dp),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = color.toHexCode(),
                style = MaterialTheme.typography.bodyLarge
            )
        }

    }
}

/**
 * A composable function that creates a slider for adjusting a float value associated with a color.
 *
 * @param label The label to display alongside the slider.
 * @param valueState The mutable state holding the current value of the slider.
 * @param color The color used for the active track of the slider.
 */
@Composable
fun ColorSlider(
    label: String,
    valueState: MutableState<Float>,
    color: Color,
) {
    /**
     * Displays a slider for adjusting the given [valueState] associated with the provided [label].
     * The slider's active track color is set to [color].
     */
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(6.dp)
    ) {
        Text(text = label)
        Slider(
            value = valueState.value,
            onValueChange = valueState.component2(),
            colors = SliderDefaults.colors(
                activeTrackColor = color
            ),
            modifier = Modifier.weight(1f)
        )
        Text(
            text = valueState.value.toColorInt().toString(),
            modifier = Modifier.width(25.dp),
            textAlign = TextAlign.End,
            style = MaterialTheme.typography.bodySmall
        )
    }
}

/**
 * Converts a float value in the range [0, 1] to an integer color component in the range [0, 255].
 *
 * @return The integer representation of the color component.
 */
fun Float.toColorInt(): Int = (this * 255 + 0.5f).toInt()

fun Color.toHexCode(): String {
    val a = (alpha * 255).toInt()
    val r = (red * 255).toInt()
    val g = (green * 255).toInt()
    val b = (blue * 255).toInt()
    return String.format("#%02X%02X%02X%02X", a, r, g, b)
}


Output:

Conclusion

In this tutorial, we've learned how to create a color picker using Jetpack Compose and Material 3 Slider components. By adjusting the RGBA values with sliders, users can easily select their desired colors.


Similar Reads