Blog Infos
Author
Published
Topics
,
Published
Create your theme
https://gist.github.com/16a45f2fc1380c9b8a38492d4d505a67f
object H19Theme {
val colors: H19Colors
@Composable
@ReadOnlyComposable
get() = LocalColors.current
val typography: H19Typography
@Composable
@ReadOnlyComposable
get() = LocalTypography.current
// We use the default material shapes
val shapes: Shapes
@ReadOnlyComposable
@Composable
get() = LocalShapes.current
}
view raw Theme1.kt hosted with ❤ by GitHub
Add your colors
val LightColors = H19Colors(
primary = Blue,
background = Color.White,
textPrimary = Color.White,
onPrimary = Color.White,
onBackground = DarkGrey,
isLight = true
)
class H19Colors(
primary: Color,
background: Color,
textPrimary: Color,
onPrimary: Color,
onBackground: Color,
isLight: Boolean
) {
var primary by mutableStateOf(primary)
private set
var background by mutableStateOf(background)
private set
var textPrimary by mutableStateOf(textPrimary)
private set
var onPrimary by mutableStateOf(onPrimary)
private set
var onBackground by mutableStateOf(onBackground)
private set
var isLight by mutableStateOf(isLight)
private set
fun copy(
primary: Color = this.primary,
background: Color = this.background,
textPrimary: Color = this.textPrimary,
onPrimary: Color = this.onPrimary,
onBackground: Color = this.onBackground,
isLight: Boolean = this.isLight
): H19Colors = H19Colors(
primary,
background,
textPrimary,
onPrimary,
onBackground,
isLight
)
fun updateColorsFrom(other: H19Colors) {
primary = other.primary
background = other.background
textPrimary = other.textPrimary
onPrimary = other.onPrimary
onBackground = other.onBackground
isLight = other.isLight
}
}
internal val LocalColors = staticCompositionLocalOf { LightColors }
view raw Color.kt hosted with ❤ by GitHub
Add your Typography
@Immutable
data class H19Typography(
val title1: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 24.sp,
letterSpacing = 0.sp,
lineHeight = 20.sp
),
val title2: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 22.sp,
letterSpacing = 0.sp,
lineHeight = 20.sp
),
val body1: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 16.sp,
letterSpacing = 0.sp,
lineHeight = 20.sp
),
val body1Bold: TextStyle = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
letterSpacing = 0.sp,
lineHeight = 20.sp
),
val body2: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
letterSpacing = 0.sp,
lineHeight = 18.sp
),
val body2Bold: TextStyle = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 14.sp,
letterSpacing = 0.sp,
lineHeight = 18.sp
),
val caption: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 12.sp,
letterSpacing = 0.sp,
lineHeight = 16.sp
),
val captionBold: TextStyle = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 12.sp,
letterSpacing = 0.sp,
lineHeight = 16.sp
),
)
internal val LocalTypography = staticCompositionLocalOf { H19Typography() }
view raw Typography.kt hosted with ❤ by GitHub

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

Jobs

Add your Shapes
internal val LocalShapes = staticCompositionLocalOf {
Shapes(
small = RoundedCornerShape(size = 15.dp),
medium = RoundedCornerShape(size = 20.dp),
large = RoundedCornerShape(size = 20.dp)
)
}
view raw Shape.kt hosted with ❤ by GitHub
Theming a Button
@Composable
fun H19WrongButton(
modifier: Modifier = Modifier,
enabled: Boolean = true,
elevation: ButtonElevation = ButtonDefaults.elevation(defaultElevation = 0.dp),
text: String,
onClick: () -> Unit
) {
Button(
modifier = modifier,
onClick = onClick,
enabled = enabled,
elevation = elevation,
) {
Text(text = text)
}
}
view raw WrongButton.kt hosted with ❤ by GitHub

And the result was:

 

 

Well, this doesn’t seem what we have defined in our theme at all. Right? So I took a look at how the button is defined in MaterialTheme

@Composable
fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
elevation: ButtonElevation? = ButtonDefaults.elevation(),
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
colors: ButtonColors = ButtonDefaults.buttonColors(),
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
)
@Composable
fun buttonColors(
backgroundColor: Color = MaterialTheme.colors.primary,
contentColor: Color = contentColorFor(backgroundColor),
disabledBackgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = 0.12f)
.compositeOver(MaterialTheme.colors.surface),
disabledContentColor: Color = MaterialTheme.colors.onSurface
.copy(alpha = ContentAlpha.disabled)
): ButtonColors = DefaultButtonColors(
backgroundColor = backgroundColor,
contentColor = contentColor,
disabledBackgroundColor = disabledBackgroundColor,
disabledContentColor = disabledContentColor
)
@Composable
fun H19Button(
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = H19Theme.shapes.small,
backgroundColor : Color = H19Theme.colors.primary,
contentColor : Color = Color.White,
elevation: ButtonElevation = ButtonDefaults.elevation(defaultElevation = 0.dp),
colors: ButtonColors = ButtonDefaults.buttonColors(
backgroundColor = backgroundColor,
contentColor = contentColor,
disabledBackgroundColor = backgroundColor.copy(alpha = 0.20f),
disabledContentColor = contentColor
),
text: String,
onClick: () -> Unit
) {
Button(
modifier = modifier,
onClick = onClick,
enabled = enabled,
shape = shape,
elevation = elevation,
colors = colors
) {
Text(text = text, color = contentColor)
}
}
view raw Button.kt hosted with ❤ by GitHub

Which in turn creates this button

 

 

CompositionLocalProvider(LocalContentAlpha provides contentColor.alpha) {
ProvideTextStyle(
value = MaterialTheme.typography.button
) {
}
}

Well, it seems that it is overriding our TextStyle with the MaterialTheme typography. Ok, we can fix that by adding our own TextStyle. So we replace our Text with the below code which will yield the final result

ProvideTextStyle(value = H19Theme.typography.captionBold) {
Text(text = text, color = contentColor)
}
}

 

Dark and Light
@Composable
fun H19Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
content: @Composable () -> Unit
) {
Surface(
modifier = modifier,
shape = shape,
content = content
)
}
view raw Surface.kt hosted with ❤ by GitHub

 

The Light Theme looks ok (But is it really?) but the dark is nothing compared to what we expected. It doesn’t seem dark at all! But now we know what the problem is. By looking again at the Compose Surface definition, we see the following:

fun Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colors.surface, <- Note this line right here
contentColor: Color = contentColorFor(color),
...
)

Yep. It’s using MaterialTheme colors. So let’s wrap it around our own surface

@Composable
fun H19Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = H19Theme.colors.background,
contentColor: Color = defaultContentColorFor(color),
content: @Composable () -> Unit
) {
Surface(
modifier = modifier,
color = color,
contentColor = contentColor,
shape = shape,
content = content
)
}
view raw H19Surface.kt hosted with ❤ by GitHub

 

 

  1. We defined background color as the color for the surface. But here is where things get interesting. Since you are defining your own theme you are free to decide what is the color you want for your surfaces, you can use any color attribute you have defined in your theme: primary, secondary, background, surface or even Banana.
  2. More avid readers may have noticed we are defining our contentColor as defaultContentColorFor(color) What is this?
@Composable
@ReadOnlyComposable
fun defaultContentColorFor(backgroundColor: Color): Color =
H19Theme.colors.contentColorFor(backgroundColor).takeOrElse { LocalContentColor.current }
private fun H19Colors.contentColorFor(backgroundColor: Color): Color {
return when (backgroundColor) {
primary -> onPrimary
background -> onBackground
else -> Color.Unspecified
}
}
view raw ContentColor.kt hosted with ❤ by GitHub
Conclusion

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
In the world of Jetpack Compose, where designing reusable and customizable UI components is…
READ MORE
blog

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE
Menu