Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[System UI Controller] I want full screen, but is not work #1205

Closed
GCZeng opened this issue Jun 17, 2022 · 10 comments · Fixed by #1251
Closed

[System UI Controller] I want full screen, but is not work #1205

GCZeng opened this issue Jun 17, 2022 · 10 comments · Fixed by #1251
Assignees

Comments

@GCZeng
Copy link

GCZeng commented Jun 17, 2022

Description

I want full screen in my app, following code:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            JetpackComposeDemoTheme {
                var isDialogVisible = remember { mutableStateOf(false) }
                JetpackComposeDemoTheme() {
                    val systemUiController: SystemUiController = rememberSystemUiController()
                    systemUiController.isSystemBarsVisible = false 

                    Box(modifier = Modifier.fillMaxSize()) {
                        Text(text = "Click here to open dialog", modifier = Modifier
                            .align(Alignment.Center)
                            .padding(32.dp)
                            .clickable {
                                isDialogVisible.value = true
                            })

                        Text(text = "Text at bottom", modifier = Modifier.align(Alignment.BottomCenter))

                        if (isDialogVisible.value) {
                            AlertDialog(
                                onDismissRequest = {},
                                confirmButton = {
                                    TextButton(onClick = { isDialogVisible.value = false })
                                    { Text(text = "OK") }
                                },
                                title = { Text(text = "Title") },
                                text = { Text(text = "Message") }
                            )
                        }

                    }
                }

            }
        }
    }
}```


![device-2022-06-17-145543](https://user-images.githubusercontent.com/3079863/174244842-b72d5423-75ba-4294-8b65-479ff2a1a505.gif)

@GCZeng
Copy link
Author

GCZeng commented Jun 17, 2022

This is a recording screen
device-2022-06-17-145543

@LozariaVinok
Copy link

I have this issue too. Have you fixed it?

@alexvanyo
Copy link
Collaborator

Hi, could you provide a bit more information about what you're expecting to happen, and what's happening instead? It's not clear to me from the GIF what the issue is.

@LozariaVinok
Copy link

LozariaVinok commented Jul 14, 2022

In my case the issue is on Samsung S8+ sdk 28
com.google.accompanist:accompanist-systemuicontroller:0.24.13-rc

I am trying to remove navigation and status bar. I put this code:

val systemUiController = rememberSystemUiController()
systemUiController.isStatusBarVisible = false // Status bar
systemUiController.isNavigationBarVisible = false // Navigation bar
systemUiController.isSystemBarsVisible = false // Status & Navigation bars
systemUiController.navigationBarDarkContentEnabled = false

As a result, the app starts without a status and navigation bars, as I expect. But when you start interacting with the screen status bar and navigation bar show again. And only after that you can truly interact with the screen.
So what I see in this gif and what I am experiencing. App starts in full screen. Person tries to click on button, but instead of showing the dialog it shows naviagation and status bar first. And dialog opens only after second click. I was trying to remove a status and naviagation bars in a dialog, and I have the same issue: to close the dialog I have to click twise and it shows status bar and navigation bar after first click.

I've checked on emulator with sdk 29: The same issue. It works fine in the emulator with sdk 32 android thought.

@alexvanyo
Copy link
Collaborator

Hi, thanks for the additional information!

It looks like the SystemUiController is currently missing a feature to allow adjusting the systemBarsBehavior, which allows configuring the behavior here for when the system bars re-appear:
https://developer.android.com/reference/androidx/core/view/WindowInsetsControllerCompat#setSystemBarsBehavior(int)

For your case, you'll probably want BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE. As a workaround before that's implemented in accompanist, you can set that directly on a windowInsetsControllerCompat that's constructed in the same manner as accompanist does.

@LozariaVinok
Copy link

Hi!
Thank you!
Workaround is working. It shows navigation bar for a moment while dialog is opening but it doesn't affect any animations so I think it's acceptable.

@GCZeng
Copy link
Author

GCZeng commented Jul 15, 2022

Hi! Thank you! Workaround is working. It shows navigation bar for a moment while dialog is opening but it doesn't affect any animations so I think it's acceptable.

How to implement, can you give me the sample code

@LozariaVinok
Copy link

I've put this code instead of accompanist usage

val window = (LocalView.current.parent as? DialogWindowProvider)?.window?:LocalView.current.context.findWindow()
if (window != null) {
WindowCompat.setDecorFitsSystemWindows(window, false)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
// Configure the behavior of the hidden system bars
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide both the status bar and the navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
}

And to find window I copied this method from accompanist

private tailrec fun Context.findWindow(): Window? =
    when (this) {
        is Activity -> window
        is ContextWrapper -> baseContext.findWindow()
        else -> null
    }

If you want to remove a status and navigation bar from dialog too you'll have to call this inside of Dialog content.

@GCZeng
Copy link
Author

GCZeng commented Jul 18, 2022

I've put this code instead of accompanist usage

val window = (LocalView.current.parent as? DialogWindowProvider)?.window?:LocalView.current.context.findWindow()
if (window != null) {
WindowCompat.setDecorFitsSystemWindows(window, false)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
// Configure the behavior of the hidden system bars
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide both the status bar and the navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
}

And to find window I copied this method from accompanist

private tailrec fun Context.findWindow(): Window? =
    when (this) {
        is Activity -> window
        is ContextWrapper -> baseContext.findWindow()
        else -> null
    }

If you want to remove a status and navigation bar from dialog too you'll have to call this inside of Dialog content.

`class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
JetpackComposeDemoTheme {
var isDialogVisible = remember { mutableStateOf(false) }
JetpackComposeDemoTheme() {
// val systemUiController: SystemUiController = rememberSystemUiController()
// systemUiController.isSystemBarsVisible = false // Status & Navigation bars
val window = (LocalView.current.parent as? DialogWindowProvider)?.window ?: LocalView.current.context.findWindow()
if (window != null) {
WindowCompat.setDecorFitsSystemWindows(window, false)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
// Configure the behavior of the hidden system bars
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide both the status bar and the navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
}

                Box(modifier = Modifier.fillMaxSize()) {
                    Text(text = "Click here to open dialog", modifier = Modifier
                        .align(Alignment.Center)
                        .padding(32.dp)
                        .clickable {
                            isDialogVisible.value = true
                        })

                    Text(text = "Text at bottom", modifier = Modifier.align(Alignment.BottomCenter))


                    if (isDialogVisible.value) {
                        AlertDialog(
                            onDismissRequest = {},
                            confirmButton = {
                                TextButton(onClick = { isDialogVisible.value = false })
                                { Text(text = "OK") }
                            },
                            title = { Text(text = "Title") },
                            text = { Text(text = "Message") }
                        )
                    }
                }
            }

        }
    }
}

}`

I've put this code instead of accompanist usage

val window = (LocalView.current.parent as? DialogWindowProvider)?.window?:LocalView.current.context.findWindow()
if (window != null) {
WindowCompat.setDecorFitsSystemWindows(window, false)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
// Configure the behavior of the hidden system bars
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide both the status bar and the navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
}

And to find window I copied this method from accompanist

private tailrec fun Context.findWindow(): Window? =
    when (this) {
        is Activity -> window
        is ContextWrapper -> baseContext.findWindow()
        else -> null
    }

If you want to remove a status and navigation bar from dialog too you'll have to call this inside of Dialog content.

Thank you very mush!
That solved my problem!

@alexvanyo
Copy link
Collaborator

Access to systemBarsBehavior should be supported in the next release, although one heads up at the moment is that retrieving the systemBarsBehavior is currently only working on API 30 and above due to an upstream androidx.core issue: https://issuetracker.google.com/issues/189366125. Setting it should work though across all APIs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants