Jetpack Compose is a modern toolkit for building native Android UI. Jetpack Compose uses fewer lines of code, strong tools, and clear Kotlin APIs to streamline and speed up UI development on Android.
Jetpack Compose is totally declarative programming, which means you can describe your user interface by invoking a set of composable
Imperative programming vs Declarative programming
Imperative programming This design focuses on the how rather than the what. A good example is XML layouts in Android. We design the widgets and components which are then rendered for the user to see and interact with.
Declarative programming This pattern is an emerging trend that allows developers to design the user interface based on the data received. This on the other hand focuses on the what. This design paradigm makes use of one programming language to create an entire application.
Advantages of JetPack Compose
- It is very fast and offers a smooth performance.
- It’s simple to learn.
- It is possible to interoperate with an imperative approach.
- Offers a better way to implement loose coupling principles.
- It is 100% made in Kotlin which makes it a modern approach in Android development
Composable Function In Jetpack Compose, Composable functions are used to define all the UI of your app programmatically. So, you need not use any XML files for the layout of the app. All you need to make a composable function is just by using the @Composable annotation to the function name. The basic syntax of a Composable function is:
@Composable
fun sampleText(text:String){
// Text is used to print the text.
Text(text)
}
how to Jetpack compose in existing XML Layout
If you want to use a Compose in your XML file, you can add this to your layout file:
<androidx.compose.ui.platform.ComposeView
android:id="@+id/my_composable"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
findViewById<ComposeView>(R.id.my_composable).setContent {
MaterialTheme {
Surface {
Text(text = "Hello!")
}
}
}
If you want the opposite, i.e. to use an XML file in your compose, you can use this:
AndroidView(
factory = { context ->
val view = LayoutInflater.from(context).inflate(R.layout.my_layout, null, false)
val textView = view.findViewById<TextView>(R.id.text)
// do whatever you want...
view // return the view
},
update = { view ->
// Update the view
}
)
Preview
You need to add @Preview() annotation before the composable function. After adding this annotation we are able to see the preview of our UI.
we can customise the preview annotation by using below features:-
Name,Background,Height and Width ,SystemUI and Device,Multiple Previews.
Text Resources
Image Resources
Button Resources
Text Field TextField is a user interface control that is used to allow the user to enter the text. This widget is used to get the data from the user as numbers or text.
mutable state - It returns an observable value for Compose. If the value changes UI gets changed automatically. TextFieldValue - A class holding information about the editing state.
In TextField() function, we use two arguments, value & onValueChange
value - We need to set the TextFieldValue. We created a variable (text) for this. And we assigned text to this argument.
onValueChange - It will return a new value (TextFieldValue) when the user enters the text.
Row and columns It provides an invisible container to hold the views or layouts. We can place a group of views/layouts inside the layouts. Row and column are layouts to arrange our views in a Linear manner.
Row - It arranges the views horizontally.
Column - It arranges the views vertically.
Example :
Modifier Modifier elements decorate or add behavior to Compose UI elements.
Recomposition Calling compose repeatedly.
State A type that holds a read-only value: It notifies the composition when value changes.
MutableState It's extension function of State. It allows us to update the value. When the value property is written to and changed, a recomposition of any subscribed RecomposeScopes will be scheduled.
Points to remember
- Compose functions can execute in any order
- Compose functions can run in parallel
List In Compose
remember remember - allows you to remember state from previous recompose invocation and just this.
remember = store the value just in case recompose is called.
Now, the second important thing is knowing when reCompose should actually be triggered and there the mutable states come to help.
mutable state = store the value and in case I update the value trigger, recompose for all elements using this data.
rememberSaveable It saves the calculated value into a Bundle (if it’s possible) on configuration change and can therefore restore it when the Activity or Fragment got recreated. For example on orientation change, split screen, or process death.
In Jetpack Compose, remember keeps state only while the screen is alive, but it’s lost on rotation or process death. rememberSaveable fixes this by storing state in SavedInstanceState, so it survives config changes and process restarts — but only for simple types (Int, String, Boolean, Parcelable, etc.). For custom objects or complex UI states (like LazyListState, PagerState, or your own data class), you need a custom Saver, which tells Compose how to "pack" your object into a saveable form (like a List, Pair, or Bundle) and "unpack" it later. This ensures your UI restores exactly where the user left off, even after process death — making custom savers the real safety net for advanced state persistence.













