Flutter应用跟随系统明暗模式动态切换主题及Scaffold颜色问询
实现Flutter应用跟随系统主题切换及动态Scaffold颜色
无需额外依赖,Flutter原生即可实现系统主题跟随
你不需要第三方包,利用Flutter内置的ThemeMode.system就能让应用自动匹配系统的深色/浅色模式,同时通过主题色动态调整Scaffold及其他组件的颜色。以下是修改后的完整代码:
修改后的main.dart
import 'package:figma_test/home/home.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { // 浅色主题配置 final lightTheme = ThemeData( useMaterial3: true, brightness: Brightness.light, primarySwatch: Colors.blue, fontFamily: 'Roboto', scaffoldBackgroundColor: const Color(0xfffafafa), // 保留你原有的浅色背景 ); // 深色主题配置 final darkTheme = ThemeData( useMaterial3: true, brightness: Brightness.dark, primarySwatch: Colors.blueGrey, fontFamily: 'Roboto', scaffoldBackgroundColor: Colors.grey[900], // 深色模式下的背景色 ); return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: lightTheme, // 浅色主题 darkTheme: darkTheme, // 深色主题 themeMode: ThemeMode.system, // 关键:跟随系统主题设置 home: const Home(), ); } }
修改后的home.dart
import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; class Home extends StatelessWidget { const Home({Key? key}) : super(key: key); final List<String> _images = [ 'img1.jpeg', 'img2.jpeg', 'img3.jpeg', 'img4.jpeg', 'img5.jpeg' ]; @override Widget build(BuildContext context) { // 判断当前是否为深色模式 final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( // 动态获取主题中的背景色 backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PreferredSize( preferredSize: const Size.fromHeight(30), child: AppBar( // 动态切换AppBar背景色 backgroundColor: isDarkMode ? Colors.grey[800] : Colors.white, systemOverlayStyle: SystemUiOverlayStyle( statusBarColor: Colors.transparent, // 动态调整状态栏亮度以适配主题 statusBarBrightness: isDarkMode ? Brightness.light : Brightness.dark, ), ), ), body: SingleChildScrollView( child: Column( children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 15), child: Row( children: [ // 动态切换图标颜色 Icon(Icons.close, color: isDarkMode ? Colors.white : Colors.black), const SizedBox(width: 13), Text( 'Product Name', style: GoogleFonts.roboto( fontWeight: FontWeight.w400, fontSize: 22, // 动态切换文字颜色 color: isDarkMode ? Colors.white : Colors.black, ), ) ], ), ), const SizedBox(height: 20), SizedBox( height: 400, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: _images.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), child: Container( height: 400, width: MediaQuery.of(context).size.width * 0.9, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('asset/images/${_images[index]}'), fit: BoxFit.fill, ), boxShadow: [ BoxShadow( // 动态切换阴影颜色 color: isDarkMode ? Colors.grey.shade800 : Colors.grey.shade400, blurRadius: 2, spreadRadius: 2, offset: const Offset(1.0, 2.0), ) ], borderRadius: BorderRadius.circular(20), // 动态切换容器底色 color: isDarkMode ? Colors.grey[800] : const Color(0xffe7edf9), ), ), ); }, ), ) ], ), ), ); } }
核心修改点说明
- 主题模式配置:通过
themeMode: ThemeMode.system让应用自动监听系统主题变化,无需手动切换按钮。 - 动态颜色适配:所有硬编码的颜色(如
Colors.white、Color(0xfffafafa))都替换为基于Theme.of(context)或isDarkMode判断的动态值,确保在两种主题下都有合适的视觉效果。 - 状态栏适配:根据当前主题调整
statusBarBrightness,避免状态栏文字与背景色冲突。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

