-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
flutter/engine
#40599Labels
a: fidelityMatching the OEM platforms betterMatching the OEM platforms betterc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Flutterplatform-webWeb applications specificallyWeb applications specifically
Description
Use case
Currently, you can set the status bar color as follows:
primaryColormust be set on webSystemUiOverlayStylemust be used in native applications
| WEB | APP |
|---|---|
web_output.mp4 |
app_output.mp4 |
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const ThemeProvider(child: MyApp()));
}
class ThemeProvider extends StatefulWidget {
const ThemeProvider({super.key, required this.child});
static ThemeProviderData of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<ThemeProviderData>()!;
final Widget child;
@override
State<ThemeProvider> createState() => _ThemeProviderState();
}
class _ThemeProviderState extends State<ThemeProvider> {
var themeMode = ThemeMode.light;
var lightTheme = ThemeData.light(useMaterial3: true).copyWith(primaryColor: Colors.blue);
var darkTheme = ThemeData.dark(useMaterial3: true).copyWith(primaryColor: Colors.blue);
void toggleThemeMode() {
setState(() {
themeMode = themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
});
}
void changePrimaryColor(Color primaryColor) {
setState(() {
lightTheme = lightTheme.copyWith(primaryColor: primaryColor);
darkTheme = lightTheme.copyWith(primaryColor: primaryColor);
});
}
@override
Widget build(BuildContext context) {
return ThemeProviderData(
themeMode: themeMode,
lightTheme: lightTheme,
darkTheme: darkTheme,
toggleThemeMode: toggleThemeMode,
changePrimaryColor: changePrimaryColor,
child: widget.child,
);
}
}
class ThemeProviderData extends InheritedWidget {
const ThemeProviderData({
super.key,
required this.themeMode,
required this.lightTheme,
required this.darkTheme,
required this.toggleThemeMode,
required this.changePrimaryColor,
required super.child,
});
final ThemeMode themeMode;
final ThemeData lightTheme;
final ThemeData darkTheme;
final VoidCallback toggleThemeMode;
final ValueChanged<Color> changePrimaryColor;
@override
bool updateShouldNotify(ThemeProviderData oldWidget) =>
themeMode != oldWidget.themeMode ||
lightTheme != oldWidget.lightTheme ||
darkTheme != oldWidget.darkTheme ||
toggleThemeMode != oldWidget.toggleThemeMode ||
changePrimaryColor != oldWidget.changePrimaryColor;
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final themeProvider = ThemeProvider.of(context);
return MaterialApp(
themeMode: themeProvider.themeMode,
theme: themeProvider.lightTheme,
darkTheme: themeProvider.darkTheme,
home: const MyHome(),
);
}
}
class MyHome extends StatefulWidget {
const MyHome({super.key});
@override
State<MyHome> createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
final math.Random _random = math.Random();
SystemUiOverlayStyle _currentStyle = SystemUiOverlayStyle.dark;
Color get randomColor => Color.fromRGBO(_random.nextInt(255), _random.nextInt(255), _random.nextInt(255), 1);
Color? appBarColor;
void changeStatusBarColor() {
setState(() {
_currentStyle = _currentStyle.copyWith(statusBarColor: randomColor);
});
}
void changeStatusBarColorBySystemCall() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: randomColor));
}
void changeAppBarBarColor() {
setState(() {
appBarColor = randomColor;
});
}
void toggleThemeMode(BuildContext context) => ThemeProvider.of(context).toggleThemeMode();
void changePrimaryColor(BuildContext context) => ThemeProvider.of(context).changePrimaryColor(randomColor);
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: _currentStyle,
child: Scaffold(
appBar: AppBar(
title: const Text('SystemOverlayStyle Test'),
backgroundColor: appBarColor,
systemOverlayStyle: _currentStyle,
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: changeStatusBarColor,
child: const Text('Change status bar color'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: changeStatusBarColorBySystemCall,
child: const Text('Change status bar color by system call'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: changeAppBarBarColor,
child: const Text('Change app bar color'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => toggleThemeMode(context),
child: const Text('Toggle theme mode'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => changePrimaryColor(context),
child: const Text('Change primary color'),
),
],
),
),
),
);
}
}Proposal
Web should use SystemUiOverlayStyle to set status bar color just like native applications.
Metadata
Metadata
Labels
a: fidelityMatching the OEM platforms betterMatching the OEM platforms betterc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Flutterplatform-webWeb applications specificallyWeb applications specifically