Today’s tutorial teaches how to use the Surface widget in Kotlin Compose Multiplatform. It is a comprehensive guide for the Surface widget. It explains each property step-by-step with sample examples, which will improve our UI capabilities in KMP(Kotlin Multiplatform) or KMM(Kotlin Multiplatform Mobile) development.
KMP Surface Widget Guide in Compose Multiplatform
In Kotin Compose Multiplatform, we can create shared UI for different platforms. In KMP, you’ll find many widgets for designing UI elements, among them the Surface widget. The Surface widget is a type of container widget with custom styling options. It provides custom shapes, shadows, custom backgrounds, and more. It can be used as a root container to create multiple child containers with a surface.
Properties of Surface widget:
- Modifier
- Shape
- color
- contentColor
- border
- elevation
1. Modifier: The modifier property allows us to set width, height, padding, clickable, Z-index, and more.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
@Composable fun App() { MaterialTheme { SurfaceWithModifierExample() } } @Composable fun SurfaceWithModifierExample() { Surface( modifier = Modifier .size(200.dp) .padding(16.dp) .clickable { println("Surface clicked!") } .shadow(8.dp, RoundedCornerShape(16.dp)) ) { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { Text( text = "Surface with Modifier", textAlign = TextAlign.Center, style = TextStyle(fontSize = 18.sp, color = Color.Black) ) } } } |
Screenshot:
2. Shape: The Surface’s shape property allows us to define different types of UI shapes as components. The Surface widget offers five types of shape properties. We will create a single program and define all the below shapes.
- Rounded Corner Shape
- Cut Corner Shape
- Circle Shape
- Rectangle Shape
- Custom shape
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
@Composable fun App() { MaterialTheme { DisplayAllShapes() } } @Composable fun DisplayAllShapes() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { // Rectangle Shape Surface( shape = RectangleShape, color = Color.Magenta, modifier = Modifier.size(100.dp) ) { Box(contentAlignment = Alignment.Center) { Text("Rectangle", textAlign = TextAlign.Center) } } // Rounded Corner Shape Surface( shape = RoundedCornerShape(16.dp), color = Color.Cyan, modifier = Modifier.size(100.dp) ) { Box(contentAlignment = Alignment.Center) { Text("Rounded", textAlign = TextAlign.Center) } } // Cut Corner Shape Surface( shape = CutCornerShape(16.dp), color = Color.DarkGray, modifier = Modifier.size(100.dp) ) { Box(contentAlignment = Alignment.Center) { Text("Cut Corners", textAlign = TextAlign.Center, color = Color.White) } } // Circle Shape Surface( shape = CircleShape, color = Color.Blue, modifier = Modifier.size(100.dp) ) { Box(contentAlignment = Alignment.Center) { Text("Circle", textAlign = TextAlign.Center, color = Color.White) } } } } |
Screenshot:
3. Color: The color property sets the background color of the Surface widget in Compose Multiplatform. It supports the HEX, RGB and color constants predefined with Compose Multiplatform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
@Composable fun App() { MaterialTheme { DisplayAllShapes() } } @Composable fun AllSurfaceWithColorCodes() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Surface( shape = RoundedCornerShape(16.dp), color = Color(0xFF6200EE), // Put 0xFF before your Hex color code. modifier = Modifier.size(100.dp) ) { Box(contentAlignment = Alignment.Center) { Text("Hex Color Code", textAlign = TextAlign.Center) } } Surface( shape = RoundedCornerShape(16.dp), color = Color(red = 0.38f, green = 0.0f, blue = 0.93f, alpha = 1.0f), modifier = Modifier.size(100.dp) ) { Box(contentAlignment = Alignment.Center) { Text("RGBA Color Code", textAlign = TextAlign.Center, color = Color.White) } } } } |
Screenshot:
4. Content Color: The content Color property sets the Color of the inner content of the Surface widget, like the Text Color. Thus, you don’t have to manually define the inner Text Color. We set up the inner text content color in this example as RED.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Composable fun DisplayAllShapesWithContentColor() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Surface( shape = RoundedCornerShape(16.dp), color = Color.Black, modifier = Modifier.size(100.dp), contentColor = Color.Red ) { Box(contentAlignment = Alignment.Center) { Text("Sample View", textAlign = TextAlign.Center) } } } } |
Screenshot:
5. Border: The Border Stroke property allows us to set a simple border around a Surface widget. It supports two properties: Border width and border color.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Composable fun DisplayAllShapesWithBorder() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Surface( border = BorderStroke(2.dp, Color.Red), shape = RoundedCornerShape(16.dp), color = Color.Cyan, modifier = Modifier.size(150.dp), ) { Box(contentAlignment = Alignment.Center) { Text("Sample View", textAlign = TextAlign.Center, color = Color.Black) } } } } |
Screenshot:
6. Elevation: The elevation property sets the shadow effect on the Surface widget. The material style automatically handles the shadow AXIS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Composable fun DisplayAllShapesWithShadow() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Surface( shape = RoundedCornerShape(16.dp), color = Color.Cyan, modifier = Modifier.size(150.dp), elevation = 40.dp ) { Box(contentAlignment = Alignment.Center) { Text("Sample View", textAlign = TextAlign.Center, color = Color.Black) } } } } |
Screenshot:
Conclusion:
I have tried my best to explain each property of the Surface widget in Compose Multiplatform. Using the surface and its properties, we can create any type of custom container view in KMP. So keep practising each of my codes, and you will learn something new in KMP. Happy coding.