What You Will Build

A dark-themed control center panel with toggle icons arranged in a grid row, plus a now-playing music card, replicating the iOS Control Center aesthetic. This pattern is useful for quick-settings panels, smart home dashboards, or any app with toggleable system controls.

Why This Pattern Matters

Building a control panel teaches you how to arrange circular icon buttons in a row, apply translucent dark card backgrounds, and create a cohesive dark-themed interface. These skills transfer directly to building settings screens, dashboards, and widget-style interfaces.

Key Concepts

  • Dark color palette with explicit hex colors for a custom dark theme.
  • forEach with list of pairs to generate toggle button rows dynamically.
  • CircleShape clips for circular icon containers with translucent backgrounds.

The Control Center Screen

@Composable
fun IosControlCenterScreen() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFF0A0A0A))
            .padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Spacer(Modifier.height(40.dp))
        Text("iOS Control Center",
            color = Color.White,
            fontWeight = FontWeight.Bold,
            fontSize = 22.sp)
        Spacer(Modifier.height(32.dp))

        // Toggle widgets card
        Card(
            Modifier.fillMaxWidth(),
            shape = RoundedCornerShape(20.dp),
            colors = CardDefaults.cardColors(
                containerColor = Color(0xFF1A1A2E)
            )
        ) {
            Column(Modifier.padding(20.dp)) {
                Row(
                    Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    Text("Widget Preview",
                        color = Color.White,
                        fontWeight = FontWeight.Bold)
                    Text("12:00",
                        color = Color.White.copy(alpha = 0.6f))
                }
                Spacer(Modifier.height(12.dp))
                Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                    listOf(
                        "Wifi" to Icons.Default.Wifi,
                        "BT" to Icons.Default.Bluetooth,
                        "GPS" to Icons.Default.LocationOn,
                        "NFC" to Icons.Default.Nfc
                    ).forEach { (label, icon) ->
                        Column(
                            horizontalAlignment = Alignment.CenterHorizontally
                        ) {
                            Box(
                                Modifier
                                    .size(48.dp)
                                    .clip(CircleShape)
                                    .background(Color.White.copy(alpha = 0.1f)),
                                contentAlignment = Alignment.Center
                            ) {
                                Icon(icon, null,
                                    tint = Color(0xFF64B5F6))
                            }
                            Text(label, fontSize = 10.sp,
                                color = Color.White.copy(alpha = 0.6f))
                        }
                    }
                }
            }
        }
        Spacer(Modifier.height(16.dp))

        // Now Playing card
        Card(
            Modifier.fillMaxWidth(),
            shape = RoundedCornerShape(16.dp),
            colors = CardDefaults.cardColors(
                containerColor = Color(0xFF1A1A2E)
            )
        ) {
            Row(
                Modifier.padding(16.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Icon(Icons.Default.MusicNote, null,
                    tint = Color(0xFF4CAF50))
                Spacer(Modifier.width(12.dp))
                Column(Modifier.weight(1f)) {
                    Text("Now Playing",
                        color = Color.White,
                        fontWeight = FontWeight.SemiBold)
                    Text("Song Title - Artist",
                        color = Color.White.copy(alpha = 0.6f),
                        fontSize = 13.sp)
                }
                Icon(Icons.Default.PlayArrow, null,
                    tint = Color.White)
            }
        }
    }
}

Tips and Pitfalls

  • Custom dark backgrounds: Using Color(0xFF0A0A0A) gives a deeper black than MaterialTheme dark colors, matching the iOS aesthetic.
  • Translucent overlays: Color.White.copy(alpha = 0.1f) creates the glass-like button backgrounds without requiring blur effects.
  • Toggle state: Add mutableStateOf(false) for each toggle and change the icon tint to indicate active/inactive states.
  • Haptic feedback: Call view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) on toggle taps for a native feel.

Minimum SDK: API 21+ with Compose BOM

Get New Tutorials by Email

No spam. Just clear, practical breakdowns you can apply right away.

Enjoy this tutorial?

Get new practical tech tutorials in your inbox.