Jetpack Compose: How to use RadioButton

Introduction

In the modern Android development landscape, Jetpack Compose is revolutionizing how developers build user interfaces. By allowing a more declarative approach to UI design, Compose simplifies the process of creating dynamic and interactive applications. One of the core elements of user interaction in any application is selecting options, often facilitated through components like radio buttons. In this article, we'll dive into an example of using Jetpack Compose to implement a set of radio buttons, enabling users to select their favorite programming language from a predefined list.

This example demonstrates not only the use of RadioButton in Jetpack Compose but also showcases several powerful features, such as state management, custom styling, and interactive text handling. We will break down each aspect of the code to understand how it all works together to create a responsive and visually appealing user interface.

Understanding the Structure

The foundation of this example is an Android application where Jetpack Compose is utilized for UI creation. At the core, a MainActivity class sets up the content for the application using the setContent function. This method replaces the traditional XML-based layouts with a more efficient, Kotlin-based, declarative approach. The layout is defined entirely within the MainContent() composable function, showcasing the simplicity and flexibility that Jetpack Compose offers.

In MainContent, a list of radio button options is defined to allow users to select their preferred programming language from choices like "Java", "Kotlin", and "C#". The state management in this example is handled using the remember function, which holds the selected option in a mutable state. By leveraging the stateful nature of Compose, the UI automatically updates whenever the selected option changes.

Designing the User Interface

The layout of this example centers around a Column composable, which vertically arranges its child elements. The background color and alignment settings enhance the visual aesthetics of the screen, making it more engaging for the user. A Card composable is used to neatly contain the radio button options, applying rounded corners, padding, and background color for a polished look.

Inside the card, a Text composable presents the question prompting the user to choose their favorite language. The text styling here includes attributes like font weight, color, and alignment, which enhance readability and visual appeal. These stylistic elements are easily adjusted through Compose's rich set of modifiers, allowing for a high degree of customization.

Implementing Radio Buttons

The core functionality revolves around displaying a list of radio buttons, which is achieved using a simple loop over the list of programming language options. Each option is paired with a RadioButton component, which is visually represented on the screen. The state of the selected radio button is determined by comparing the current item to the stored selection. When a user clicks on a radio button, the state is updated, and the change is reflected instantly in the UI.

To enhance the interactivity, the ClickableText composable is used alongside each radio button. This allows users to select an option not only by clicking the radio button itself but also by tapping on the text label next to it. The text is styled using buildAnnotatedString, allowing customization such as bold text, which makes the labels stand out. This combination of radio buttons and clickable text provides a more intuitive user experience.

Displaying the Selected Option

At the bottom of the Column, a Text composable displays the currently selected programming language. This text updates dynamically as users interact with the radio buttons, showcasing the reactivity and state management capabilities of Jetpack Compose. The text is styled with attributes like font size, color, and alignment to ensure it is visually distinct from other elements on the screen. The immediate feedback provided to users enhances the interactivity of the application, making it more engaging.

Summary

This example demonstrates the power and flexibility of Jetpack Compose when it comes to building interactive UI components like radio buttons. By leveraging Compose’s declarative approach, state management, and rich styling capabilities, developers can create intuitive and responsive user interfaces with minimal effort. This example provides a practical guide to implementing radio buttons while also introducing best practices for managing state and enhancing user interaction through clickable text.

As developers continue to adopt Jetpack Compose, understanding its core components and state management will be essential for building efficient and scalable Android applications. This example serves as a stepping stone for exploring more advanced features of Compose, paving the way for developing complex and dynamic UIs with ease.


MainActivity.kt

package com.cfsuman.jetpackcompose

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainContent()
        }
    }


    @Composable
    fun MainContent(){
        val radioOptions = listOf("Java", "Kotlin", "C#")
        val (selectedOption, onOptionSelected) = remember {
            mutableStateOf(radioOptions[1])
        }

        Column(
            Modifier
                .fillMaxWidth()
                .background(Color(0xFFEDEAE0)),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Card(
                backgroundColor = Color(0xFFFAE7B5),
                modifier = Modifier
                    .padding(15.dp)
                    .fillMaxWidth(0.90f),
                elevation = 8.dp,
                shape = RoundedCornerShape(12.dp),
            ) {
                Column(
                    Modifier.padding(10.dp)
                ) {
                    Text(
                        text = "Which is your most favorite?.",
                        fontStyle = FontStyle.Normal,
                        fontWeight = FontWeight.Bold,
                        modifier = Modifier
                            .padding(5.dp),
                        textAlign = TextAlign.Start,
                        color = Color(0xFF3D2B1F)
                    )

                    radioOptions.forEach { item ->
                        Row(
                            Modifier
                                .padding(5.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(
                                selected = (item == selectedOption),
                                onClick = { onOptionSelected(item) }
                            )

                            val annotatedString = buildAnnotatedString {
                                withStyle(
                                    style = SpanStyle(
                                        fontWeight = FontWeight.Bold
                                        )
                                ){
                                    append("  $item  ")
                                }
                            }

                            ClickableText(
                                text = annotatedString,
                                onClick = {
                                    onOptionSelected(item)
                                }
                            )
                        }
                    }
                }
            }

            Text(
                text = "You selected : $selectedOption",
                fontSize = 22.sp,
                fontStyle = FontStyle.Normal,
                fontWeight = FontWeight.Normal,
                fontFamily = FontFamily.SansSerif,
                modifier = Modifier
                    .padding(bottom = 15.dp)
                    .fillMaxWidth(),
                textAlign = TextAlign.Center,
                color = Color(0xFF665D1E)
            )
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }
}
More android jetpack compose tutorials