Getting started with jetpack compose – Basic components

Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs.

To learn more about the jetpack compose internals, Please check the official documents. In this post, I am focusing on creating material components using jetpack compose.

Jetpack compose official page

Jetpack compose tutorial by android developers


If you’re new to Compose, I highly recommend going through the following articles:

Getting started with jetpack compose – Modifiers

Getting started with jetpack compose – Layouts

Getting started with jetpack compose – ConstraintLayout


Also, check out the video from android developers.

jetpack compose

Setup jetpack compose on android studio

Method 1 – Creating a new Jetpack compose Project

Create a jetpack compose project

Create New Project by selecting “Empty Compose Activity“, It will add all the Gradle dependencies in the Gradle file and MainAcitivity to accept composable. So, straightaway we can start working on the project.

Method 2 – Migrate Existing Android Studio Project

Add jetpack compose version in the project build.gradle file.

buildscript {
    ext {
        compose_version = '1.0.0'
    }
    ...
}Code language: JavaScript (javascript)

Then, add the build features and compose options in your module-level build.gradle file.

compileOptions {
        sourceCompatibility "1.8"
        targetCompatibility "1.8"
    }
    kotlinOptions {
        jvmTarget = '1.8'
        useIR = true
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
        kotlinCompilerVersion '1.5.10'
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }Code language: JavaScript (javascript)

The next step is to add the jetpack compose dependencies in the gradle file.

implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    implementation 'androidx.activity:activity-compose:1.3.1'
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"Code language: JavaScript (javascript)

Finally, change your MainAcitivity.kt to extend ComponentActivity. Also, add the setContent to accept the composable content on oncreate().

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

Ok. the setup Is completed. The next step is to create compose components.

Before getting started into jetpack components, you should know about the layouts, Modifiers, and mutablestate in kotlin compose. Please check the below links for your reference.

Layouts in Compose

State and Jetpack Compose

Compose modifiers

Jetpack compose components

Text

Text is a central piece of any UI, and Jetpack Compose makes it easier to display or write text. 

Displaying text

@Composable
fun SimpleText() {
    Text(text = "Hello World!")
}Code language: JavaScript (javascript)
text

Reading text from resource

@Composable
fun SimpleText() {
    Text(text = stringResource(R.string.hello_world))
}

Changing the text color

@Composable
fun SimpleText() {
    Text(text = stringResource(R.string.hello_world), color = Color.Blue)
}

Changing the font size / font weight / font Family / font style

Text(text = stringResource(R.string.hello_world), fontSize = 20.sp)
Text(text = stringResource(R.string.hello_world), fontSize = 20.sp, fontWeight = FontWeight.Bold)
Text(text = stringResource(R.string.hello_world), fontSize = 20.sp, fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic)
Text(text = stringResource(R.string.hello_world), fontSize = 20.sp, fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic , fontFamily = FontFamily.Monospace)
text style

Multiple styles in a text

@Composable
fun DisplayAnnotatedString() {
    val context = LocalContext.current
    Text(buildAnnotatedString {
        withStyle(style = SpanStyle(color = Color.Gray)) {
            append("Text")
        }
        append(" Jetpack")
        withStyle(style = SpanStyle(color = Color.Red, fontFamily = FontFamily.Monospace)) {
            append(" compose")
        }
    })
}Code language: JavaScript (javascript)
Span text

Text Field

TextField allows users to enter and modify text.

@Composable
fun DisplayTextField() {
    var name by remember {
        mutableStateOf("")
    }
    TextField(value = name, onValueChange = { it ->
        name = it
    }, label = { Text(text = "Username") })
}Code language: JavaScript (javascript)
textfield

Outlined TextField

@Composable
fun DisplayOutlinedTextField() {
    var name by remember {
        mutableStateOf("")
    }
    OutlinedTextField(value = name, onValueChange = { it ->
        name = it
    }, label = { Text(text = "Username") })
}Code language: JavaScript (javascript)
outlined textfield

Styling TextField

  • singleLine
  • maxLines
  • textStyle
@Composable
fun DisplayTextField() {
    var name by remember {
        mutableStateOf("")
    }
    TextField(value = name, onValueChange = { it ->
        name = it
    }, label = { Text(text = "Username", style = TextStyle(fontSize = 18.sp)) },
    maxLines = 1, modifier = Modifier.padding(8.dp),
    textStyle = TextStyle(color = Color.Red, fontFamily = FontFamily.Monospace))
}Code language: JavaScript (javascript)

Keyboard options

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction
fun DisplayTextField() {
    var password by remember {
        mutableStateOf("Hello")
    }
    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}Code language: JavaScript (javascript)

Button

A Button has an onClick-Function. You can add a Text-Composable or any other Composables as child elements of the Button.

@Composable
fun DisplayPrimaryButton() {
    val context = LocalContext.current
    Button(onClick = {
        Toast.makeText(context, "Primary Button clicked", Toast.LENGTH_SHORT).show()
    }, Modifier.padding(4.dp)) {
        Text(
            text = "Primary Button")
    }
}Code language: JavaScript (javascript)
button

Outlined Button

@Composable
fun DisplayOutlinedButton() {
    val context = LocalContext.current
    OutlinedButton(onClick = { Toast.makeText(context, "Outlined Button clicked", 
        Toast.LENGTH_SHORT).show()
    }, Modifier.padding(4.dp)) {
        Text(
            text = "Outlined Button"
        )
    }
}Code language: JavaScript (javascript)
outlined button

Styling Button

@Composable
fun DisplayPrimaryButton() {
    val context = LocalContext.current
    Button(onClick = {
        Toast.makeText(context, "Primary Button clicked", Toast.LENGTH_SHORT).show()
    }, Modifier.padding(4.dp)) {
        Text(
            text = "Primary Button",
            style = TextStyle(fontSize = 22.sp,fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold)
        )
    }
}Code language: JavaScript (javascript)
Button style

Checkbox

@Composable
fun DisplayCheckBox() {
    var checkStatus by remember {
        mutableStateOf(false)
    }
    Row {
        Checkbox(checked = checkStatus, onCheckedChange = {
            checkStatus = it
        })
        Text(text = "Checkbox", Modifier.clickable { checkStatus = !checkStatus })
    }
}Code language: JavaScript (javascript)
Checkbox

Radio Button

@Composable
fun DisplayRadioButton() {
    val cities = listOf("Chennai", "Mumbai", "Pune")
    val (selected, onOptionSelected) = remember {
        mutableStateOf(cities[0])
    }
    Column(Modifier.padding(4.dp)) {
        cities.forEach { text ->
            Row(modifier = Modifier.padding(4.dp)) {
                RadioButton(selected = selected == text, onClick = {
                    onOptionSelected(text)
                })
                Text(text = text, Modifier.clickable { onOptionSelected(text) })
            }
        }
    }
}Code language: PHP (php)
Radio button

Switch

@Composable
fun DisplaySwitch() {
    val context = LocalContext.current
    var switchStatus by remember {
        mutableStateOf(false)
    }
    Row(Modifier.padding(8.dp)) {
        Text(text = "Light on/off")
        Switch(checked = switchStatus, onCheckedChange = {
            switchStatus = it
            Toast.makeText(context, "Light ${if (it) "on" else "off"}", Toast.LENGTH_SHORT).show() })
    }
}Code language: PHP (php)
Switch

Surface

The surface is like a view in android. So can add background color, shape, elevation, border, etc.

@ExperimentalMaterialApi
@Composable
fun DisplaySurface() {
    val context = LocalContext.current
    Surface(shape = RoundedCornerShape(8.dp), elevation = 8.dp, onClick = {
        Toast.makeText(
            context,
            "Surface clicked",
            Toast.LENGTH_SHORT
        ).show()},border = BorderStroke(2.dp, Color.Blue), modifier = Modifier.padding(8.dp).width(100.dp)) {
        Text(text = "Surface",Modifier.padding(8.dp), textAlign = TextAlign.Center)
    }
}Code language: JavaScript (javascript)
Surface

Circular Progress Indicator

A CircularProgressIndicator can be used to display progress in a circular shape.

Indeterminate

When you use the CircularProgressIndicator without the progress parameter, it will run forever.

@Composable
fun DisplayCircularProgressBar() {
        CircularProgressIndicator(strokeWidth = 8.dp, color = Color.Gray, modifier = Modifier.padding(4.dp))
}

Determinate

When you set a value to the progress parameter, the indicator will be shown with that progress.

@Composable
fun DisplayCircularProgressBar() {
        CircularProgressIndicator(progress = 0.5f, strokeWidth = 8.dp, color = Color.Gray, modifier = Modifier.padding(4.dp))
}
Circular progressbar

Linear Progress Indicator

A LinearProgressIndicator can be used to display progress in a linear line, also known as a progress bar.

Indeterminate

When you use the LinearProgressIndicator without the progress parameter.

@Composable
fun DisplayLinearProgressBar() {
    LinearProgressIndicator(backgroundColor = Color.Blue, color = Color.Black, modifier = Modifier.padding(4.dp))
}

Determinate

When you set a value to the progress parameter, the indicator will be shown with that progress.

@Composable
fun DisplayLinearProgressBar() {
    LinearProgressIndicator(progress = 0.5f, backgroundColor = Color.Blue, color = Color.Black, modifier = Modifier.padding(4.dp))
}
Linear progressbar

Slider

Sliders allow users to make selections from a range of values.

@Composable
fun DisplaySlider() {
    Spacer(modifier = Modifier.padding(4.dp))
    var sliderValue by remember {
        mutableStateOf(10.0f)
    }
    Text(text = sliderValue.toInt().toString(), modifier = Modifier.fillMaxWidth(),textAlign = TextAlign.Center)
    Slider(value = sliderValue, onValueChange = {sliderValue = it}, valueRange = 0f..100f)
}Code language: JavaScript (javascript)
Slider

Slider with steps

@Composable
fun DisplaySliderWithStepper() {
    var sliderValue by remember {
        mutableStateOf(25.0f)
    }
    Text(text = sliderValue.toInt().toString(), modifier = Modifier.fillMaxWidth(),textAlign = TextAlign.Center)
    Slider(value = sliderValue, onValueChange = {sliderValue = it}, steps = 3, valueRange = 0f..100f)
}Code language: JavaScript (javascript)
Slider with steps

Spacer

The spacer component is used to display an empty space. Width and (or) height can be set for Spacer using the Modifier object.

@Composable
fun DisplaySpacer() {
    Spacer(modifier = Modifier
        .padding(8.dp)
        .height(40.dp)
        .fillMaxWidth()
        .background(Color.Gray))
}
Spacer

Thanks for reading. Also, you can download this example from GITHUB.

If you like this post, you can follow me on

Facebook

Twitter

Medium


Posted

in

by

Comments

4 responses to “Getting started with jetpack compose – Basic components”

  1. […] Getting started with jetpack compose – Basic components […]

  2. […] Getting started with jetpack compose – Basic components (howtodoandroid.com) […]

Leave a Reply

Your email address will not be published. Required fields are marked *