Jetpack Compose: Compose Basics
In this article, we will explore some common UI components that can be used while developing an application using Jetpack Compose.
Jetpack Compose is the declarative UI approach in native Android app development. It is currently in the pre-alpha stage. This article is the continuation of my previous article.
In Jetpack compose we can build a beautiful layout in a few minutes. It is based on material design principles and provides material design components out of the box.
Compose is built to support material design principles. Many of its UI elements implement material design out of the box.
Note: Updated for compose version
0.1.0-dev12
This article covers the following UI components and some stylings on them.
- Text
- Image
- Image Icon
- Column
- Row
Text
High level element that displays text and provides semantics/accessibility information
Let's start from MainActivity.kt
created on a new project.
package com.example.composebasics
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.Composable
import androidx.ui.core.Text
import androidx.ui.core.setContent
import androidx.ui.material.MaterialTheme
import androidx.ui.tooling.preview.Preview
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Greeting("Android")
}
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview
@Composable
fun DefaultPreview() {
MaterialTheme {
Greeting("Android")
}
}
In the above code, composable function Greeting
includes another composable function Text
which appends the text Hello
as a prefix to the parameter name
and renders the text when the application is run.
The preview is displayed by another composable function DefaultPreview
annotated with @Preview
. The rendered preview is below.
On hovering the mouse pointer above Text
, we can figure out the possible params that can be used.
We can add any parameters depending on our design requirements. Let's apply some of them on the Text
as below.
@Composable
fun Greeting(name: String) {
val longText = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
Text(
text = "Hello $name!\n$longText", // longText in next line
modifier = Modifier.padding(16.dp),
color = Color.Red,
fontSize = TextUnit(20),
fontStyle = FontStyle.Italic,
letterSpacing = TextUnit(5),
textDecoration = TextDecoration.Underline,
textAlign = TextAlign.Start,
lineHeight = TextUnit(50),
overflow = TextOverflow.Ellipsis,
softWrap = false,
maxLines = 2,
onTextLayout = { textLayoutResult: TextLayoutResult ->
//Callback that is executed when a new text layout is calculated.
},
style = TextStyle.Default
)
}
The parameters for Text
can be in any order and we can use only those we need. The rendered preview for Greeting
is below.
Image
Image
can be used to display image resources stored on the drawable folderres-> drawable
as well as material image icons. For remote images we will discuss in coming articles.
@Composable
fun DrawableImage() {
val imageModifier = Modifier
.preferredHeightIn(maxHeight = 180.dp)
.padding(16.dp)
.fillMaxWidth()
.clip(shape = RoundedCornerShape(8.dp))
val image = imageResource(R.drawable.morning_begin)
Image(image, modifier = imageModifier, contentScale = ContentScale.Crop)
}@Preview
@Composable
fun DrawableImagePreview() {
MaterialTheme {
DrawableImage()
}
}
For material icons:
To use material icons we have to include following material icon dependency in the app build.gradle
.
implementation("androidx.ui:ui-material-icons-extended:$compose_version")
In the main activity, the composable can be written as below.
@Composable
fun IconImage() {
Image(
asset = Icons.Filled.Face, // material icon
modifier = Modifier.preferredSize(40.dp),
colorFilter = ColorFilter.tint(Color.Black),
contentScale = ContentScale.Fit
)
}
Column
A layout composable that places its children in a vertical sequence.
The column is a composable layout in which other composable components can be placed in a vertical manner one after another. Let's place above two composable layouts in the Column.
@Composable
fun VerticalLayout() {
Column {
DrawableImage()
Greeting("Android")
}
}@Preview
@Composable
fun VerticalLayoutPreview() {
MaterialTheme {
VerticalLayout()
}
}
The first one appears at the top and others appears below one after another as a book of stacks in a table.
Row
A layout composable that places its children in a horizontal sequence.
The Row is a composable layout in which other composable components can be placed in a horizontal manner side by side. Let’s create a row containing IconImage()
.
@Composable
fun HorizontalLayout() {
Row {
IconImage()
IconImage()
IconImage()
IconImage()
IconImage()
}
}@Preview
@Composable
fun HorizontalLayoutPreview() {
MaterialTheme {
HorizontalLayout()
}
}
Combination of Row and Layout
Any composable layouts can be placed inside another composable. Lets put a row inside a column.
@Composable
fun CombineLayout() {
Column {
DrawableImage()
Greeting("Android")
Row(modifier = Modifier.padding(16.dp)) {
IconImage()
IconImage()
IconImage()
IconImage()
IconImage()
}
}
}@Preview
@Composable
fun CombineLayoutPreview() {
MaterialTheme {
CombineLayout()
}
}
Wrapping Up
Let's combine all the above components in the main activity and build the app.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Column {
DrawableImage()
Greeting("Android")
Row(modifier = Modifier.padding(16.dp)) {
IconImage()
IconImage()
IconImage()
IconImage()
IconImage()
}
}
}
}
}
}
More detailed use of Rows and Columns can be found in this my sample application which calculates BMI based on entered age and weight.
Reference:
1. Android Compose Tutorial
2. Compose Sample