How to create a Dice roller App using Kotlin and Jetpack
The Dice Roller app we are building in this tutorial provides a unique experience just like a real world dice roller with six sides.A user can rotate the dice and randomly get different sides.
Kotlin is a modern,expressive and powerful language used to write android applications.On the other hand,Jetpack compose provides powerful composables such as Text,Button and Image enabling developers write interactive applications with intuitive user intterfaces.
Setting up project on Android Studio
To create the dice roller app,ensure you have Android Studio(Iguana) with Android SDK Platform 34 installed on your computer.
- Open Android Studio then choose File,New,New Project then choose Empty Activity.
2.Name the app Dice Roller App or any name you may prefer then click Next.
Code display with Hello World
3.Once the app runs, it will have three views,Code,Split and Design.Code view allows you to see only the code while split view enables you to see both code and preview while design allows only preview alone.Once that app builds a Hello World Screen will appear which is modifiable to finally get a complete Dice Roller App.
package com.example.dicerollerapp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.dicerollerapp.ui.theme.DiceRollerAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
DiceRollerAppTheme {
Greeting("Android")
}
}
Hello World screen
Try Kodaschool for free
Click below to sign up and get access to free web, android and iOs challenges.
Modifying starter code to Dice Roller App
4.Modify the code by removing GreetingPreview() function and creating DiceWithButtonAndImage() with its composable.Additionally,create a DiceRollerApp() function with its preview and composable the call it in DiceRollerTheme lambda.Ensure any greeting logic in setContent {} lambda is removed.Do not forget to append @ symbol before preview and composable.
Adding Composables
5.Next call DiceWithButtonAndImage() function inside DiceRollerApp().Inside DiceWithButtonAndImage() function add a Modifier whose work is to control the behavior of composables such as Text,Button and Image.
package com.example.dicerollerapp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.dicerollerapp.ui.theme.DiceRollerAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerAppTheme {
DiceRollerApp()
}
}
}
}
@Preview(showBackground = true)
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage()
}
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
}
Layout and Styling
6.Add styling to the Layout by using fillMaxSize() method with the Modifier to ensure it fills the entire screen.Moreover,in order to center all the items add wrapContentSize() method and passing Alignment.Center argument.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerAppTheme {
DiceRollerApp()
}
}
}
}
@Preview(showBackground = true)
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage()
}
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center
) {
}
7.Next is creating a vertical layout to ensure items are centered.Add a Column method with a Modifier and passing horizontalAlignment argument set to Alignment.CenterHorizontally.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerAppTheme {
DiceRollerApp()
}
}
}
}
@Preview(showBackground = true)
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage()
}
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center
) {
Column (
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {}
}
8.Add Button and Image composables.To add a Button define a string in string.xml found in the res/values folder in the Dice Roller project.Name the string Rotate.Also add a Button with a Text composable within the lambda body of Column method.Ensure there is an onClick argument to trigger click events.Ensure you pass the string resource ID for rotate to stringResource() function.
9.Add an image for a Dice that you may download from pexel.com or pixabay or any stock free site.Find a zip file for dice images from this link Dice .Unzip then use the images.To add the image to your project go to Tools,Windows,then Resource Manager in Android studio then click the + button to allow you import the drawables.Select the Dice image then upload.For the image to appear above the button,place the Image composable at the top of Button composable.To create some space between Image and Button,apply a Space Composable.
Keeping track of states
10.Finally,create a function called result that will help in looping through the six dice images uploaded.Since the dice are from 1 to 6, we assign the range to result and pass the random() method so that if clicked the dice appear in a random order.Apply remember composable to store objects in memory.Additionally pass a mutableStateOf() function with 1 as an argument that enables refreshing of the screen.
11.Always ensure that you import all composables by clicking Alt and Enter or right clicking on the highlighted composable and selecting the required import.
package com.example.dicerollerapp
import android.media.Image
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role.Companion.Image
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.dicerollerapp.ui.theme.DiceRollerAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerAppTheme {
DiceRollerApp()
}
}
}
}
@Preview(showBackground = true)
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage()
}
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier .fillMaxSize() .wrapContentSize(Alignment.Center)) {
var result by remember { mutableStateOf( 1) }
val imageResource = when(result) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
Column (
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = imageResource),
contentDescription = result.toString()
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { result = (1..6).random()}) {
Text(stringResource(R.string.rotate))
}
}
}
Complete Dice Roller App