Screens are flashing when I navigate to them in Dark theme using Navigation-compose
Asked Answered
U

4

8

I am using Navigation-Compose in my app :

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTheme {
                val navController = rememberNavController()
                NavHost(navController = navController, startDestination = Screens.Dashboard.title) {
                    composable(Screens.Dashboard.title) {
                        DashboardScreen(navController)
                    }
                    composable(
                        Screens.Section.title, arguments = listOf(
                            navArgument(LINK) {
                                type = AssetParamType()
                            }
                        )
                    ) {
                        SectionDetailsScreen(navController)
                    }
                }
            }
        }
    }

I have a separate appBar in every screen such as :

@Composable
fun DashboardScreen(
    navController: NavHostController,
    viewModel: DashboardViewModel = hiltViewModel()
) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Box(
                        contentAlignment = Alignment.Center,
                        modifier = Modifier.fillMaxSize()
                    ) {
                        Text(text = stringResource(id = R.string.label_dashboard))
                    }
                },
                elevation = 8.dp,
                modifier = Modifier.clip(
                    RoundedCornerShape(bottomStart = 18.dp, bottomEnd = 18.dp)
                )
            )
        },
        content = {
            Content(viewModel = viewModel) { dashboard ->
                VerticalCollection(dashboard) { link ->
                    val json = Uri.encode(Gson().toJson(link))
                    navController.navigate(
                        Screens.Section.title.replace
                            ("{${LINK}}", json)
                    )
                }
            }
        })
}

Screens are flashing when I navigate between them in Dark theme. There is a small flashing on appBar when dark theme is off. How to resolve it?

Source code of my project can be found here : https://github.com/alirezaeiii/Navigation-Compose

Addenda :

I found out that if we get use of accompanist library as indicated in this link : TopAppBar flashing when navigating with Compose Navigation Flashing issue will be resolved, but it is a must to use accompanist.

Uptrend answered 14/2, 2022 at 7:5 Comment(1)
Wrapping the app in a surface component solved it for me. https://mcmap.net/q/643508/-topappbar-flashing-when-navigating-with-compose-navigationDoublure
U
6

For anyone having this issue, make sure you've wrapped your NavHost composable inside a Surface (normally nested right after the Theme composable).

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourAppNameTheme {
                Surface {
                    NavHost(
                        ...
                    ) {
                        composable(Screen.Home.route) { Home() }
                        ...
                        composable(Screen.Settings.route) { Settings() }
                    }
                }
            }
        }
    }
}
Unsex answered 7/10, 2023 at 1:22 Comment(0)
H
4

I fixed this issue without using the accompanist lib (and overriding the animation effects).

Did you ensure that your AppTheme applied from you manifest.xml uses DayNight ?

By default your project might use:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

You can replace it with:
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">

Hydrogenolysis answered 2/11, 2022 at 17:11 Comment(0)
W
2

2023 Update:

If you're created new project recently, as it is using material3 by default, you'll need to change the res/values/theme.xml file from:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="Theme.[YourApp]" parent="android:Theme.Material.Light.NoActionBar" />
</resources>

To:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="Theme.[YourApp]" parent="android:Theme.Material.NoActionBar" />
</resources>

And remove the Light from the default theme.

Weightlessness answered 23/6, 2023 at 6:57 Comment(1)
I tried this - it didn't work for meNonperformance
P
1
<style name="Theme.App.Starting" parent="Theme.SplashScreen">
   <item name="android:windowBackground">@color/colorPrimaryDark</item>

I solved screen flashing like this but topBar is flashing. Change windowBackground according to your dark or light theme using

 LaunchedEffect(isDarkMode) {
                @ColorRes val backGroundColor =
                    if (isDarkMode) R.color.colorPrimaryDark else R.color.colorPrimary
                window.decorView.setBackgroundColor(
                    ContextCompat.getColor(
                        this@MainActivity,
                        backGroundColor
                    )
                )
            }

When you do this, your background will be the same as your Compose background, so it won't be flashing.

I solved topper flashing too

I changed my top bar colors

 CenterAlignedTopAppBar(
        colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
            containerColor = Color.Transparent,
        )
    

Also try to implement dark mode like now in android app.you don't need my first recommendation.They solve more cleaner way

Now in android sample

Phoenicia answered 14/6, 2023 at 21:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.