Open the Starter project in the 06-use-material-design directory of the m3-cjp-materials repo, in Android Studio Koala or later.
Wait for the project to build.
This is the same project you have worked on so far. In this demo, you’ll create a custom theme for your app.
If you expand the res directory, you’ll notice two fonts in the font directory. These are the fonts you’ll use to create a custom-type scale.
First, create a ui.theme package in the root app package. Next, create a file named Color.kt in the same package. This will host your color palette. Add the following code to the file:
import androidx.compose.ui.graphics.Color
val colorPrimary = Color(0xFF006837)
val colorPrimaryDark = Color(0xFF004012)
val colorAccent = Color(0xFFc75f00)
These colors represent the Kodeco brand palette.
Next, create a new file in the ui.theme package, and name it Type.kt. Enter the following into the file:
import androidx.compose.material.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.sp
import com.yourcompany.android.githubusers.R
val rubik = FontFamily(
Font(R.font.rubik_regular, FontWeight.Normal),
)
val chivo = FontFamily(
Font(R.font.chivo_bold, FontWeight.Bold)
)
val Typography = Typography(
h3 = TextStyle(
fontSize = 36.sp,
fontFamily = rubik,
fontWeight = FontWeight.ExtraBold,
letterSpacing = (-8).sp
),
h4 = TextStyle(
fontSize = 24.sp,
fontFamily = rubik,
fontWeight = FontWeight.ExtraBold,
letterSpacing = (-8).sp
),
h5 = TextStyle(
fontSize = 24.sp,
fontFamily = chivo,
fontWeight = FontWeight.Bold
),
h6 = TextStyle(
fontSize = 16.sp,
fontFamily = chivo,
fontWeight = FontWeight.Bold
),
subtitle1 = TextStyle(
fontSize = 16.sp,
fontFamily = chivo,
fontWeight = FontWeight.Normal
),
subtitle2 = TextStyle(
fontSize = 14.sp,
fontFamily = chivo,
fontWeight = FontWeight.Bold
),
body2 = TextStyle(
fontSize = 14.sp,
fontFamily = rubik,
fontWeight = FontWeight.Normal,
lineHeight = 22.sp
),
button = TextStyle(
fontSize = 14.sp,
fontFamily = rubik,
fontWeight = FontWeight.Normal
),
overline = TextStyle(
fontSize = 14.sp,
fontFamily = rubik,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
letterSpacing = (3).sp
)
)
Here, you’re using the two fonts to create a custom type scale. The components of the app will use this.
Next, create a Shape.kt file in the same package and enter the following:
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Shapes
import androidx.compose.ui.unit.dp
val Shapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(8.dp),
large = RoundedCornerShape(16.dp)
)
Here, you created a shape definition to be used by the app.
Finally, you’ll tie it all together in a custom theme.
In the same package, create a new file called Theme.kt and enter the following:
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
private val DarkColorPalette = darkColors(
primary = colorPrimaryDark,
primaryVariant = colorPrimary,
secondary = colorAccent
)
private val LightColorPalette = lightColors(
primary = colorPrimary,
primaryVariant = colorPrimaryDark,
secondary = colorAccent
)
Here, you created a dark and light mode palette using your color definitions. Next, add the following to the file:
@Composable
fun GithubUserAppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
Here, you’ve defined a new GithubUserAppTheme that uses the color types and shape definition you created earlier. isSystemInDarkTheme() is a Composable that informs you whether the system is using a dark theme or not. Based on the returned value, you choose between the light and dark color palettes.
First, modify the GitHubRepoCard Composable to use the shapes and types.
For the wrapping Card, use the shape as follows:
Card(shape = MaterialTheme.shapes.large)
Next, apply the typographic scales to the Text components. Change the repo name text composable to use h5:
Text(
text = repo.name,
style = MaterialTheme.typography.h5,
)
Next, change the description to use body1:
Text(
text = it,
style = MaterialTheme.typography.body1
)
Finally, change the URL text to use the subtitle text style, and secondary color:
Text(
text = repo.htmlUrl,
style = MaterialTheme.typography.subtitle2,
color = MaterialTheme.colors.secondary,
textDecoration = TextDecoration.Underline
)
To see the theme in action, wrap your preview composable with the theme, as follows:
@Preview(uiMode = UI_MODE_NIGHT_YES)
@Preview(uiMode = UI_MODE_NIGHT_NO)
@Composable
fun PreviewGitHubRepoCard() {
GithubUserAppTheme {
GitHubRepoCard(
/*...*/
)
}
}
Finally, to use the theme in the entire app, apply it on the setContent block and wrap your GitHubRepoList composable.
setContent {
GithubUserAppTheme {
val state by viewModel.state.observeAsState()
Column(modifier = Modifier.padding(16.dp)) {
state?.forEach { repo ->
GitHubRepoCard(repo)
Spacer(modifier = Modifier.height(16.dp))
}
}
}
}
That concludes this demo. Continue with the lesson for a summary.