Reputation: 201
I am trying to create a full-screen widget in Flutter, where both the system status bar at the top and the navigation bar at the bottom are hidden. According to the information I could find you can achieve this by calling SystemChrome.setEnabledSystemUIMode
.
However, when I test the app on my device (OnePlus 8 Pro, Oxygen OS 13.1, Android 13), I don't get the behaviour that I expect. If the status bar is not hidden, then the app takes up the entire height of the screen, and the status bar is overlaid on top of it:
When I hide the status bar the status bar icons disappear, but a black bar appears instead, which seems to be the same height as the status bar:
I have no problems with hiding the bottom navigation bar.
I tried to use:
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky)
and
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: [],
)
I thought maybe the specific widget that I used caused the problem, so tested it with SafeArea
, Scaffold
, Container
and Card
, but get always get the same result.
I have created a simple app to demonstrate the behaviour:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
enum SystemUIOptions { all, statusBar, navigationBar, immersiveSticky }
void main() {
WidgetsFlutterBinding.ensureInitialized;
runApp(const SystemChromeTester());
}
class SystemChromeTester extends StatefulWidget {
const SystemChromeTester({super.key});
@override
State<SystemChromeTester> createState() => _SystemChromeTesterState();
}
class _SystemChromeTesterState extends State<SystemChromeTester> {
SystemUIOptions? selectedUIOption = SystemUIOptions.all;
void printViewInsets() {
print('System UI option: ${selectedUIOption!.name}');
print('Height: ${MediaQuery.of(context).size.height}');
print('Viewinsets top: ${MediaQuery.of(context).viewInsets.top}');
print('Viewinsets bottom: ${MediaQuery.of(context).viewInsets.bottom}');
print('Viewpadding: ${MediaQuery.of(context).viewPadding}');
print('Padding: ${MediaQuery.of(context).padding}');
}
void toggleSystemUI(SystemUIOptions? selected) {
switch (selected) {
case SystemUIOptions.all:
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
break;
case SystemUIOptions.statusBar:
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [SystemUiOverlay.top]);
break;
case SystemUIOptions.navigationBar:
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: [SystemUiOverlay.bottom],
);
break;
case SystemUIOptions.immersiveSticky:
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
break;
default:
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
}
setState(() {
selectedUIOption = selected;
});
}
@override
Widget build(BuildContext context) {
printViewInsets();
return MaterialApp(
home: Scaffold(
// appBar: AppBar(),
backgroundColor: Colors.amber,
resizeToAvoidBottomInset: false,
body: Center(
child: Column(
children: [
RadioListTile(
title:
const Text('Top (status bar) and bottom (navigation bar)'),
value: SystemUIOptions.all,
groupValue: selectedUIOption,
onChanged: toggleSystemUI,
),
RadioListTile(
title: const Text('Top (status bar) only'),
value: SystemUIOptions.statusBar,
groupValue: selectedUIOption,
onChanged: toggleSystemUI,
),
RadioListTile(
title: const Text('Bottom (navigation bar) only'),
value: SystemUIOptions.navigationBar,
groupValue: selectedUIOption,
onChanged: toggleSystemUI,
),
RadioListTile(
title: const Text('Immersive sticky'),
value: SystemUIOptions.immersiveSticky,
groupValue: selectedUIOption,
onChanged: toggleSystemUI,
),
],
),
),
),
);
}
}
Is this a Flutter bug, is it specific to the device/OS I am using, or am I missing something obvious?
Upvotes: 3
Views: 258