This might be an odd question, but is sp as defined in Jetpack Compose different from sp in XML? We have an XML style that we use in TextView defined as follows:
<style name="Body">
<item name="android:textSize">12sp</item>
<item name="android:lineSpacingExtra">8dp</item>
<item name="android:letterSpacing">-0.03125</item>
</style>
We also have a font family defined in XML and applied to the theme via android:fontFamily and fontFamily:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
<font
app:font="@font/some_font_regular"
app:fontStyle="normal"
app:fontWeight="500" />
<font
app:font="@font/some_font_italic"
app:fontStyle="italic"
app:fontWeight="500" />
<font
app:font="@font/some_font_bold"
app:fontStyle="normal"
app:fontWeight="700" />
<font
app:font="@font/cera_pro_bold_italic"
app:fontStyle="italic"
app:fontWeight="700" />
</font-family>
Moving to Jetpack Compose, we have a data class that contains TextStyles and the definition of the font family where we tried to mimic the definition in the XML:
data class AppTypography(
private val someFontFamily: FontFamily = FontFamily(
Font(R.font.some_font_regular, FontWeight.W500, FontStyle.Normal),
Font(R.font.some_font_bold, FontWeight.W700, FontStyle.Normal),
Font(R.font.some_font_italic, FontWeight.W500, FontStyle.Italic),
Font(R.font.some_font_pro_bold_italic, FontWeight.W700, FontStyle.Italic),
),
// ...
val body: TextStyle = TextStyle(
fontFamily = someFontFamily,
fontWeight = FontWeight.Normal,
fontSize = 12.sp,
lineHeight = 24.sp
),
// ...
)
internal val LocalTypography = staticCompositionLocalOf { AppTypography() }
This data class is in turn used in this object, which provides access to typography, colors, etc:
object AppTheme {
val colors: AppColors
@Composable
get() = LocalColors.current
val typography: AppTypography
@Composable
get() = LocalTypography.current
val dimensions: AppDimensions
@Composable
get() = LocalDimensions.current
val shapes: AppShapes
@Composable
get() = LocalShapes.current
}
Finally, we use this object as an actual Composable:
@Composable
fun AppTheme(
colors: AppColors = lightColors(),
content: @Composable () -> Unit
) {
val rememberedColors = remember { colors.copy() }.apply { updateColorsFrom(colors) }
CompositionLocalProvider(
LocalColors provides rememberedColors,
LocalTypography provides AppTheme.typography,
LocalDimensions provides AppTheme.dimensions,
LocalShapes provides AppTheme.shapes,
) {
content()
}
}
We then use the body style in one of our Texts:
Text(
modifier = Modifier.padding(start = 16.dp),
text = stringResource(stringResourceId),
style = AppTheme.typography.body,
color = AppTheme.colors.onSurface
)
Comparing the text size in the traditional View system versus in Compose (XML on the left, Compose on the right):
Both use 12sp as text size, but the Compose one looks smaller. To be fair even the icon looks smaller as well. I'm not sure what could cause this difference, maybe the outer Composable's paddings may have an effect? Anyone faced a similar behaviour when migrating their views to Compose?
