Skip to content

Instantly share code, notes, and snippets.

@hectorAguero
Last active September 25, 2023 06:00
Show Gist options
  • Save hectorAguero/f7888ab718d183b27758dadf8151efd6 to your computer and use it in GitHub Desktop.
Save hectorAguero/f7888ab718d183b27758dadf8151efd6 to your computer and use it in GitHub Desktop.
Flutter Android Transparent Navigation Bar
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<void> main() async {
try{
WidgetsFlutterBinding.ensureInitialized();
final theme = (await SharedPreferences.getInstance()).getString("theme_mode");
runApp(
MyApp(
themeMode:
theme != null ? ThemeMode.values.byName(theme) : ThemeMode.system,
),
);
} catch(_){
runApp(const MyApp());
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key, this.themeMode = ThemeMode.system});
/// Should be loaded from shared preferences on main() and save in each change
final ThemeMode themeMode;
@override
Widget build(BuildContext context) {
// Set Android Bar Transparent(needs systemNavigationBarColor set to transparent)
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
final ValueNotifier<ThemeMode> notifier = ValueNotifier(themeMode);
notifier.addListener(() {
print(notifier.value.name);
SharedPreferences.getInstance()
.then((prefs) => prefs.setString("theme_mode", notifier.value.name));
});
return ValueListenableBuilder<ThemeMode>(
builder: (context, mode, child) {
final isDark = mode == ThemeMode.dark ||
(mode == ThemeMode.system &&
MediaQuery.of(context).platformBrightness == Brightness.dark);
SystemChrome.setSystemUIOverlayStyle(
//isDark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark
SystemUiOverlayStyle(
//NavigationBar
systemNavigationBarColor: Colors.transparent,
systemNavigationBarContrastEnforced: false,
systemNavigationBarIconBrightness:
isDark ? Brightness.light : Brightness.dark,
//StatusBar
statusBarColor: Colors.transparent,
statusBarIconBrightness:
isDark ? Brightness.light : Brightness.dark,
),
);
return MaterialApp(
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
themeMode: mode,
home: HomePage(themeNotifier: notifier),
);
},
valueListenable: notifier,
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key, required this.themeNotifier});
final ValueNotifier<ThemeMode> themeNotifier;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool isBottomAppBarVisible = false;
bool isAppBarVisible = false;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context).colorScheme;
final themeName = widget.themeNotifier.value.name == 'system'
? 'system ${MediaQuery.of(context).platformBrightness.name}'
: widget.themeNotifier.value.name;
return Scaffold(
appBar: isAppBarVisible ? AppBar(title: const Text('Title')) : null,
body: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => Container(
height: 100,
color: index.isEven
? theme.background
: (index % 3 == 0 ? Colors.grey.shade700 : theme.onBackground),
),
),
bottomNavigationBar: isBottomAppBarVisible
? NavigationBar(
destinations: const [
NavigationDestination(
icon: Icon(Icons.home),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.bookmarks),
label: 'Bookmarks',
),
NavigationDestination(
icon: Icon(Icons.business),
label: 'Business',
),
],
)
: null,
floatingActionButton: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
FloatingActionButton.extended(
label: Text("Switch theme: $themeName"),
onPressed: () {
widget.themeNotifier.value = ThemeMode.values[
(widget.themeNotifier.value.index + 1) %
ThemeMode.values.length];
},
),
const SizedBox(height: 8),
FloatingActionButton.extended(
label: Text('${isAppBarVisible ? 'Hide' : 'Show'} AppBar'),
onPressed: () => setState(
() => isAppBarVisible = !isAppBarVisible,
),
),
const SizedBox(height: 8),
FloatingActionButton.extended(
label: Text(
'${isBottomAppBarVisible ? "Hide" : "Show"} NavigationBar',
),
onPressed: () => setState(
() => isBottomAppBarVisible = !isBottomAppBarVisible,
),
),
const SizedBox(height: 8),
FloatingActionButton(
child: const Icon(Icons.list_alt_outlined),
onPressed: () {
showModalBottomSheet<void>(
context: context,
clipBehavior: Clip.hardEdge,
builder: (context) => const SafeArea(
top: false,
child: ColoredBox(
color: Color(0xFF616161),
child: SizedBox(
height: 200,
child: Center(
child:
Text('This is a modal bottom sheet with SafeArea'),
),
),
),
),
);
},
),
],
),
);
}
}
@hectorAguero
Copy link
Author

Added ValueNotifier to changeTheme

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment