Sirop4ik
Sirop4ik

Reputation: 5233

Why jetpack compose text colors looks different from the preview?

I am new to Jetpack compose. I am following the tutorial and the problem is that according to the tutorial the text color is black on the preview as well as on the real device (in the tutorial)

enter image description here

on my preview I also see the color as black, however, when I run the app on my two different devices I see the color is white.

What am I missing here?

UPD

package com.example.composableexmp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.composableexmp.ui.theme.ComposableExmpTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp {
                TopHeader()
            }
        }
    }
}

@Composable
fun MyApp(content: @Composable () -> Unit) {
    ComposableExmpTheme {
        Surface(
            color = MaterialTheme.colors.background
        ) {
            content()
        }
    }
}

@Preview
@Composable
fun TopHeader(totalPerPerson: Double = 0.0) {
    Surface(
        modifier = Modifier
            .fillMaxWidth()
            .height(150.dp)
            .clip(shape = RoundedCornerShape(corner = CornerSize(12.dp))),
        color = Color(color = 0xFFE9D7F7)
    ) {
        Column(
            modifier = Modifier.padding(12.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
             val total = "%.2f".format(totalPerPerson)

            Text(
                text = "Total Per Person",
                style = MaterialTheme.typography.h5
            )

            Text(
                text = "$$total",
                style = MaterialTheme.typography.h4,
                fontWeight = FontWeight.ExtraBold
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposableExmpTheme {
        MyApp {
            Text(text = "Hello Again")
        }
    }
}

Upvotes: 1

Views: 2658

Answers (2)

IsawU
IsawU

Reputation: 450

Could it be that perhaps your devices are below Android 12?

The generated Composable in Theme.kt has this signature

@Composable
fun ComposableExmpTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    // Dynamic color is available on Android 12+
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
…

Making the app use dynamic color scheme whenever available.

The IDE previews will appear using dynamicDarkColorScheme(context) and dynamicLightColorScheme(context), somewhat simulating a behavior of Android 12+ devices. While your physical devices (if they have Android <12) use your DarkColorScheme and LightColorScheme.

For a quick fix, just use your theme as:

ComposableExmpTheme(dynamicColor = false) {
    …
}

Or see the code in Theme.kt and adjust it according to your needs.


Sadly, using @Preview(apiLevel = Build.VERSION_CODES.R) does nothing to the color scheme displayed in the preview.

Upvotes: 2

Thracian
Thracian

Reputation: 66536

Colors change based on your theme. You should inspect Theme.kt in ui.theme folder.

private val DarkColorScheme = darkColorScheme(
    primary = Purple80,
    secondary = PurpleGrey80,
    tertiary = Pink80
)

private val LightColorScheme = lightColorScheme(
    primary = Purple40,
    secondary = PurpleGrey40,
    tertiary = Pink40

    /* Other default colors to override
    background = Color(0xFFFFFBFE),
    surface = Color(0xFFFFFBFE),
    onPrimary = Color.White,
    onSecondary = Color.White,
    onTertiary = Color.White,
    onBackground = Color(0xFF1C1B1F),
    onSurface = Color(0xFF1C1B1F),
    */
)

And how these colors are selected

@Composable
fun MyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    // Dynamic color is available on Android 12+
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        }
        darkTheme -> DarkColorScheme
        else -> LightColorScheme
    }
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
            ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
        }
    }

    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography,
        content = content
    )
}

On Surface is the color of the Text provided by Surface. Based on your theme it can be the values set to these colors.

enter image description here

enter image description here

Upvotes: 2

Related Questions