Jetpack Compose: Getting Started

Aug 1 2023 · Kotlin 1.8.10, Android 13, Android Studio Flamingo

Part 1: Make a Simple Interface

03. Building a Simple Layout

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 02. Creating Your First Composable Function Next episode: 04. Leverage Modifiers

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 03. Building a Simple Layout

A layout can be defined as the structure of a user interface in an application, either an Activity or a Fragment. This is usually made up of a hierachy of Composables. Jetpack Compose provides several Composables that you can use to build layouts. We will discuss the Row, Column, Box and Scaffold Composables in this course.

Let us get started with the Column and Row Composables.

The Column and Row Composables are used to arrange other Composables in a vertical and horizontal manner respectively. They are usually used to build simple layouts.

The Column Composable has one mandatory argument and three optional arguments. The mandatory argument is named content and requires a @Composable () -> Unit object. This argument is used to specify the children of the layout Composable.

One optional argument is named verticalArrangement and requires a Arrangement.Vertical object. This argument is used to specify the vertical arrangement of the Composable. The default value is Arrangement.Top.

Another optional argument is named horizontalAlignment and requires a Alignment.Horizontal object. This argument is used to specify the horizontal alignment of the Composable. The default value is Alignment.Start.

Lastly, The other argument is named modifier and requires a Modifier object. This argument is used to modify the layout of the Composable.

The Row Composable has one mandatory argument and three optional arguments. The mandatory argument is named content and requires a @Composable () -> Unit object. This argument is used to specify the children of the layout Composable.

The optional arguments are named horizontalArrangement, verticalAlignment and content and require a Arrangement.Horizontal, Alignment.Vertical and a lambda that returns Unit respectively. These arguments are used to specify the horizontal arrangement, vertical alignment and the Composables that will be arranged horizontally respectively.

Adding a Column Composable

Let us add a new package named components to the com.kodeco.android.ui package. This package will contain all the reusable Composables that we will use to build our layouts.

Add a new file named FoodCategoryItem.kt, this file will have a Composable that will display individual food categories. Each category will accept an image and a name as parameters to the Composable.

@Composable
fun FoodCategoryItem(
    @DrawableRes icon: Int,
    category: String
){

}

We can add a Column Composable to the FoodCategoryItem Composable. The Column Composable will have an Image Composable and a Text Composable as its children.

@Composable
fun FoodCategoryItem(){
    @DrawableRes icon: Int,
    category: String
}{

    Column(
        modifier = Modifier.size(75.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
    ){

        Image(
            modifier = Modifier.size(75.dp),
            painter = painterResource(id = icon),
            contentDescription = null,
        )

        Text(
            modifier = Modifier.padding(top = 5.dp),
            text = category,
            textAlign = TextAlign.Center,
            fontWeight = FontWeight.Bold,
            style = MaterialTheme.typography.bodyMedium
        )

    }

}

Adding a Row Composable

Add a new file named ProfileBar.kt, this file will have a Composable that will display a profile bar. The bar will contain two images and a text Composable.

@Composable
fun ProfileBar(){

}

Add a Row Composable to the ProfileBar Composable. The Row Composable will have two Image Composables and a Text Composable as its children.

@Composable
fun ProfileBar(){

    Row(
        modifier = Modifier.fillMaxWidth()
            .padding(16.dp),
    ){

        Image(
            modifier = Modifier.size(50.dp),
            painter = painterResource(id = R.drawable.ic_profile),
            contentDescription = null,
        )

        Text(
            text = "Hello, Kodeco",
            style = MaterialTheme.typography.bodyLarge,
        )

        Image(
            modifier = Modifier.size(50.dp),
            painter = painterResource(id = R.drawable.ic_notifications),
            contentDescription = null,
        )

    }

}

Box and Scaffold Composables

Sometimes, we do not need to arrange Composables in a vertical or horizontal manner. We just need to stack them on top of each other. This is where the Box Composable comes in. The Box Composable is used to stack Composables on top of each other.

A Box Composable has one mandatory argument and three optional arguments. The mandatory argument is named modifier and requires a Modifier object. This argument is used to modify the layout of the Composable.

  • The contentAlignment is an optional argument that requires a Alignment object. This argument is used to specify the alignment of the Composable. The default value is Alignment.TopStart.

  • The content argument is a lambda that returns Unit. This argument is used to specify the Composables that will be stacked on top of each other.

  • The propagateMinConstraints argument is a boolean that specifies whether the minimum constraints of the Composable should be propagated to its children. The default value is false.

The Scaffold Composable is used to build screens that have a top app bar, a bottom navigation bar and a floating action button. It is usually used to build screens that have a Material Design look and feel.

With the Scaffold, you can even specify a color scheme for the container and the content in the layout.

The Scaffold Composable has the first argument being the Modifier. This argument is used to modify the layout of the Composable.

All the different slots in the UI of the Scaffold are provided as arguments.

  • The topBar argument is used to specify the Composable that will be displayed in the top app bar slot.

  • The bottomBar argument is used to specify the Composable that will be displayed in the bottom navigation bar slot.

  • The floatingActionButton argument is used to specify the Composable that will be displayed in the floating action button slot.

  • The floatingActionButtonPosition argument is used to specify the position of the floating action button. The default value is FloatingActionButtonPosition.End.

  • The content argument is a lambda that returns Unit. This argument is used to specify the Composables that will be displayed in the content slot.

Adding a Box Composable

We can modify the ProfileBar Composable to hold the trailing image in a specific shape and size.

@Composable
fun ProfileBar(){

    Row(
        modifier = Modifier.fillMaxWidth()
            .padding(16.dp),
    ){

        Image(
            modifier = Modifier.size(50.dp),
            painter = painterResource(id = R.drawable.ic_profile),
            contentDescription = null,
        )

        Text(
            text = "Hello, Kodeco",
            style = MaterialTheme.typography.bodyLarge,
        )

        Box(
            modifier = Modifier
                    .background(color = Color.White, shape = CircleShape)
                    .size(50.dp)
                    .clip(CircleShape),
            contentAlignment = Alignment.Center,
        ){
            Image(
                painter = painterResource(id = R.drawable.ic_notifications),
                contentDescription = null,
            )
        }

        

    }

}

Adding a Scaffold Composable

We can start by creating a new package named screens in the com.kodeco.android.ui package. This package will contain all the screens / pages of the app.

Let us now create a new file named HomeScreen.kt in the com.kodeco.android.ui package. This file will have a Composable that will display the home screen of the app.

@Composable
fun HomeScreen(){

}

In this Composable, you can add a Scaffold Composable. The Scaffold Composable will have a Column Composable as its content.

The topAppBar argument of the Scaffold Composable will have a ProfileBar Composable as its value.

@Composable
fun HomeScreen(){

    Scaffold(
        topBar = {
            ProfileBar()
        }
    ){

    }

}

The bottomBar argument of the Scaffold Composable will have a Text Composable as its value for now.

We will also add a Column Composable to the Scaffold Composable. The Column Composable will have a Text Composable as its child.

@Composable
fun HomeScreen(){

    Scaffold(
        topBar = {
            ProfileBar()
        },
        bottomBar = {
            Text(text = "Bottom Bar")
        }
    ){

        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally,
        ){
            Text(text = "Home Screen")
        }

    }

}

Since Scaffold comes from the Material3 library, we will need to annotate the HomeScreen Composable with @OptIn(ExperimentalMaterial3Api::class).

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen(){

    Scaffold(
        topBar = {
            ProfileBar()
        },
        bottomBar = {
            Text(text = "Bottom Bar")
        }
    ){

        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally,
        ){
            Text(text = "Home Screen")
        }

    }

}

Conclusion

We have been able to see how different layout Composables can be used to place items on the screen. We covered the Column, Row, Box and Scaffold Composables. We will explore more about layout Composables in proceeding sessions.

In our next episode, we will look at how we can leverage the power of Modifier objects to customize the look and feel of Composables.