mark
mark

Reputation: 473

Jetpack Compose: Text remains black even when the theme is dark

The text in the app still remains black even if the theme is set to dark and background is dark. Just take a look at the code and screenshots below.

Theme.kt (here, in DarkColorPalette, I set onSurface and onBackground to Color.White but it doesn't help)

private val DarkColorPalette = darkColors(
    primary = PastelGreen,
    secondary = PastelGreenTransparent,
    onPrimary = Color.White,
    onSecondary = PastelGreen,
    onBackground = Color.White,
    onSurface = Color.White
)

private val LightColorPalette = lightColors(
    primary = PastelGreen,
    secondary = PastelGreenTransparent,
    onPrimary = Color.White,
    onSecondary = PastelGreen,
)

@Composable
fun EschoolTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {

    MaterialTheme(
        colors = if (darkTheme) DarkColorPalette else LightColorPalette,
        typography = typography,
        shapes = Shapes,
        content = content
    )
}

Type.kt

val manropeFamily = FontFamily(
    Font(R.font.light, FontWeight.Light),
    Font(R.font.regular, FontWeight.Normal),
    Font(R.font.medium, FontWeight.Medium),
    Font(R.font.bold, FontWeight.Bold),
    Font(R.font.extra_bold, FontWeight.ExtraBold),
    Font(R.font.extra_light, FontWeight.ExtraLight),
    Font(R.font.semi_bold, FontWeight.SemiBold),
)

val typography =
    Typography(
        defaultFontFamily = manropeFamily,
        h5 = TextStyle(fontWeight = FontWeight.Bold, fontSize = 23.sp,),
        button = TextStyle(letterSpacing = 0.sp, fontWeight = FontWeight.Bold)
    )

Code of the screen (don't take care about Russian texts)

@Composable
fun Onboarding() {
    EschoolTheme {
        Column(
            modifier = Modifier
                .padding(20.dp)
        ) {
            Column(
                Modifier
                    .weight(1f)
                    .fillMaxWidth()
            ) {
                Spacer(modifier = Modifier.weight(1f))
                Image(
                    painter = painterResource(id = R.drawable.icon),
                    contentDescription = "Иконка приложения со смайлом, смотрящим через монокль",
                    modifier = Modifier
                        .align(Alignment.CenterHorizontally)
                        .size(100.dp)
                )
                Spacer(modifier = Modifier.height(30.dp))
                Text(
                    "Добро пожаловать в eschool!",
                    textAlign = TextAlign.Center,
                    style = MaterialTheme.typography.h5,
                    modifier = Modifier.align(
                        Alignment.CenterHorizontally
                    )
                )
                Spacer(modifier = Modifier.weight(1f))
            }
            Text(
                "Здесь ты можешь быстро делиться домашкой и расписанием со своими одноклассниками без всяких мессенжджеров. Используй это приложение как школьный дневник, в который ты обычно записываешь д/з и расписание. Всё, что ты записываешь сюда, будет сразу видно и твоим одноклассникам. Тебе больше не придётся ждать ответа от твоих одноклассников в мессенджерах или наоборот отвечать им. Чтобы начать пользоваться приложением, надо войти в аккаунт.",
                style = MaterialTheme.typography.body2
            )
            Spacer(modifier = Modifier.height(20.dp))
            LargeButton(onClick = { /*TODO*/ }, secondary = true) {
                Text("У меня уже есть аккаунт")
            }
            Spacer(modifier = Modifier.height(10.dp))
            LargeButton(onClick = { /*TODO*/ }) {
                Text("Я тут в первый раз")
            }
        }
    }
}

Screenshots

Dark theme Light theme
Dark theme screenshot enter image description here

If you need more code, ask me, I'll provide it

Upvotes: 20

Views: 6655

Answers (6)

Michael S
Michael S

Reputation: 1865

Passing style = TextStyle(color = MaterialTheme.colorScheme.onBackground) to ClickableText() resolves the immediate problem. This is the way to get to onBackground color in Material3.

Upvotes: 0

Niqrs
Niqrs

Reputation: 21

You can use MaterialTheme.colors.onSurface color for your Text color parameter instead of wrapping Text with the Surface to get absolutely the same onSurface color.

YourAppTheme(
    darkTheme = true
) {
    Text(
        text = "text with dark theme color",
        color = MaterialTheme.colors.onSurface
    )
}

Upvotes: 1

Timur
Timur

Reputation: 760

You can use custom text composable:

@Composable
fun DayNightText(
text: String,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colorScheme.onSurface, // Change default color here
fontSize: TextUnit = TextUnit.Unspecified,
fontStyle: FontStyle? = null,
fontWeight: FontWeight? = null,
fontFamily: FontFamily? = null,
letterSpacing: TextUnit = TextUnit.Unspecified,
textDecoration: TextDecoration? = null,
textAlign: TextAlign? = null,
lineHeight: TextUnit = TextUnit.Unspecified,
overflow: TextOverflow = TextOverflow.Clip,
softWrap: Boolean = true,
maxLines: Int = Int.MAX_VALUE,
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
) {
    Text(
    text = text,
    modifier = modifier,
    color = color,
    fontSize = fontSize,
    fontStyle = fontStyle,
    fontWeight = fontWeight,
    fontFamily = fontFamily,
    letterSpacing = letterSpacing,
    textDecoration = textDecoration,
    textAlign = textAlign,
    lineHeight = lineHeight,
    overflow = overflow,
    softWrap = softWrap,
    maxLines = maxLines,
    onTextLayout = onTextLayout,
    style = style)
}

Upvotes: 1

John Doe
John Doe

Reputation: 1131

You can specify text styles in your app's theme like this:

@Composable
fun MyTheme(
    content: @Composable () -> Unit
) {
    MaterialTheme(
        colors = DarkColors,
        typography = Typography(body1 = TextStyle(color = Color.White), button = TextStyle(color = Color.Black)),
        content = content
    )
}

Then wrap your content in MyTheme:

MyTheme {
    AppContent()
}

Upvotes: 2

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363587

The color in the Text is defined by the color parameter or applying a TextStyle. The default value is Color.Unspecified.
If color = Color.Unspecified and style has no color set, this will be LocalContentColor which provides a default Color.Black color if not specified.

You have different options:

  • You can add as parent container a Surface. In this case it will be used the Colors.onSurface specified in your theme.
    Surface(){
      Column(){
        Text(){...}
      }
    }
  • Use the color parameter in the Text composable

  • Use the style parameter:

Text(style = LocalTextStyle.current.copy(color = Red)){...}
  • Use a custom LocalContentColor to override the default Black color
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.xxx) {
      Text()
}

Upvotes: 36

Phil Dukhov
Phil Dukhov

Reputation: 87655

You can specify Text color with using color or using style values.

When there's no value specified for both of these, Text on compose uses LocalContentColor value, which is default to Black and doesn't depend on the theme

If you wanna change default text color for the whole app, the best solution is to override this value right after introducing your theme:

setContent {
    YourTheme {
        CompositionLocalProvider(
            LocalContentColor provides MaterialTheme.colors.onSecondary // replace this with needed color from your pallete
        ) {
            Content()
        }
    }
}

Also you can override this value again using CompositionLocalProvider to any part of your app

Upvotes: 6

Related Questions