Android jetpack compose theme: color, typography and shape
Example of defining colors with Jetpack Compose, Color.kt
import androidx.compose.ui.graphics.Color val Red200 = Color(0xfff297a2) val Red300 = Color(0xffea6d7e) val Red700 = Color(0xffdd0d3c) val Red800 = Color(0xffd00036) val Red900 = Color(0xffc20029)
Example of defining typography with Jetpack Compose, Type.kt, the fonts are in res files in res/font/ folder.
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.unit.sp import com.codelab.theming.R /** * https://fonts.google.com/specimen/Montserrat */ private val Montserrat = FontFamily( Font(R.font.montserrat_regular), Font(R.font.montserrat_medium, FontWeight.W500), Font(R.font.montserrat_semibold, FontWeight.W600) ) /** * https://fonts.google.com/specimen/Domine */ private val Domine = FontFamily( Font(R.font.domine_regular), Font(R.font.domine_bold, FontWeight.Bold) ) val JetnewsTypography = Typography( h4 = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W600, fontSize = 30.sp ), h5 = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W600, fontSize = 24.sp ), h6 = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W600, fontSize = 20.sp ), subtitle1 = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W600, fontSize = 16.sp ), subtitle2 = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W500, fontSize = 14.sp ), body1 = TextStyle( fontFamily = Domine, fontWeight = FontWeight.Normal, fontSize = 16.sp ), body2 = TextStyle( fontFamily = Montserrat, fontSize = 14.sp ), button = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W500, fontSize = 14.sp ), caption = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.Normal, fontSize = 12.sp ), overline = TextStyle( fontFamily = Montserrat, fontWeight = FontWeight.W500, fontSize = 12.sp ) )
Example of defining shape with Jetpack Compose, Shape.kt
import androidx.compose.foundation.shape.CutCornerShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Shapes import androidx.compose.ui.unit.dp val JetnewsShapes = Shapes( small = CutCornerShape(topStart = 8.dp), medium = CutCornerShape(topStart = 24.dp), large = RoundedCornerShape(8.dp) )
Example of using the Theme with Jetpack Compose, Home.kt
import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.Card import androidx.compose.material.ContentAlpha import androidx.compose.material.Divider import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.ListItem import androidx.compose.material.LocalContentAlpha import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Palette import androidx.compose.material.primarySurface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.codelab.theming.R import com.codelab.theming.data.Post import com.codelab.theming.data.PostRepo import com.codelab.theming.ui.finish.theme.JetnewsTheme import java.util.Locale @Composable fun Home() { val featured = remember { PostRepo.getFeaturedPost() } val posts = remember { PostRepo.getPosts() } JetnewsTheme { Scaffold( topBar = { AppBar() } ) { innerPadding -> LazyColumn(contentPadding = innerPadding) { item { Header(stringResource(R.string.top)) } item { FeaturedPost( post = featured, modifier = Modifier.padding(16.dp) ) } item { Header(stringResource(R.string.popular)) } items(posts) { post -> PostItem(post = post) Divider(startIndent = 72.dp) } } } } } @Composable private fun AppBar() { TopAppBar( navigationIcon = { Icon( imageVector = Icons.Rounded.Palette, contentDescription = null, modifier = Modifier.padding(horizontal = 12.dp) ) }, title = { Text(text = stringResource(R.string.app_title)) }, backgroundColor = MaterialTheme.colors.primarySurface ) } @Composable fun Header( text: String, modifier: Modifier = Modifier ) { Surface( color = MaterialTheme.colors.onSurface.copy(alpha = 0.1f), contentColor = MaterialTheme.colors.primary, modifier = modifier.semantics { heading() } ) { Text( text = text, style = MaterialTheme.typography.subtitle2, modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp) ) } } @Composable fun FeaturedPost( post: Post, modifier: Modifier = Modifier ) { Card(modifier) { Column( modifier = Modifier .fillMaxWidth() .clickable { /* onClick */ } ) { Image( painter = painterResource(post.imageId), contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier .heightIn(min = 180.dp) .fillMaxWidth() ) Spacer(Modifier.height(16.dp)) val padding = Modifier.padding(horizontal = 16.dp) Text( text = post.title, style = MaterialTheme.typography.h6, modifier = padding ) Text( text = post.metadata.author.name, style = MaterialTheme.typography.body2, modifier = padding ) PostMetadata(post, padding) Spacer(Modifier.height(16.dp)) } } } @Composable private fun PostMetadata( post: Post, modifier: Modifier = Modifier ) { val divider = " • " val tagDivider = " " val text = buildAnnotatedString { append(post.metadata.date) append(divider) append(stringResource(R.string.read_time, post.metadata.readTimeMinutes)) append(divider) val tagStyle = MaterialTheme.typography.overline.toSpanStyle().copy( background = MaterialTheme.colors.primary.copy(alpha = 0.1f) ) post.tags.forEachIndexed { index, tag -> if (index != 0) { append(tagDivider) } withStyle(tagStyle) { append(" ${tag.uppercase(Locale.getDefault())} ") } } } CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) { Text( text = text, style = MaterialTheme.typography.body2, modifier = modifier ) } } @OptIn(ExperimentalMaterialApi::class) @Composable fun PostItem( post: Post, modifier: Modifier = Modifier ) { ListItem( modifier = modifier .clickable { /* todo */ } .padding(vertical = 8.dp), icon = { Image( painter = painterResource(post.imageThumbId), contentDescription = null, modifier = Modifier.clip(shape = MaterialTheme.shapes.small) ) }, text = { Text(text = post.title) }, secondaryText = { PostMetadata(post) } ) } @Preview("Post Item") @Composable private fun PostItemPreview() { val post = remember { PostRepo.getFeaturedPost() } JetnewsTheme { Surface { PostItem(post = post) } } } @Preview("Featured Post") @Composable private fun FeaturedPostPreview() { val post = remember { PostRepo.getFeaturedPost() } JetnewsTheme { FeaturedPost(post = post) } } @Preview("Featured Post • Dark") @Composable private fun FeaturedPostDarkPreview() { val post = remember { PostRepo.getFeaturedPost() } JetnewsTheme(darkTheme = true) { FeaturedPost(post = post) } } @Preview("Home") @Composable private fun HomePreview() { Home() }
Reference:
https://github.com/googlecodelabs/android-compose-codelabs/tree/main/ThemingCodelab
Search within Codexpedia
Custom Search
Search the entire web
Custom Search
Related Posts