如何为Flutter应用的深色/浅色模式设置不同背景图?
基于adaptive_theme包的实现方案
首先修正你代码里的两处小错误:decorarion 拼写应为 decoration,fit: BoxFit.cover 要放在 DecorationImage 内部,否则不会生效。
接下来借助adaptive_theme包的主题状态判断来切换背景图:
- 确保你已经在main函数中完成了AdaptiveTheme的初始化配置(这是使用该包的基础):
void main() async { WidgetsFlutterBinding.ensureInitialized(); final savedThemeMode = await AdaptiveTheme.getThemeMode(); runApp( AdaptiveTheme( light: ThemeData.light(), dark: ThemeData.dark(), initial: savedThemeMode ?? AdaptiveThemeMode.system, builder: (theme, darkTheme) => MaterialApp( theme: theme, darkTheme: darkTheme, home: YourHomePage(), ), ), ); }
- 在你的页面代码中,通过
AdaptiveTheme.of(context).mode获取当前生效的主题模式,动态选择背景图:
return SafeArea( child: Container( decoration: BoxDecoration( image: DecorationImage( // 根据当前主题模式选择对应图片 image: AssetImage( AdaptiveTheme.of(context).mode == AdaptiveThemeMode.dark ? 'assets/dark_background.png' : 'assets/light_background.png', ), fit: BoxFit.cover, ), ), child: Scaffold( backgroundColor: Colors.transparent, // 必须设为透明,否则会覆盖背景图 body: // 你的页面内容 ), ), );
这样无论是系统自动切换主题,还是用户通过adaptive_theme提供的手动切换功能改变主题,背景图都会同步更新。
原生Flutter实现方案(无需第三方包)
如果你不想依赖adaptive_theme,直接用Flutter原生API也能实现同样效果:
通过MediaQuery.of(context).platformBrightness获取当前系统的亮度模式,动态选择背景图:
return SafeArea( child: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage( MediaQuery.of(context).platformBrightness == Brightness.dark ? 'assets/dark_background.png' : 'assets/light_background.png', ), fit: BoxFit.cover, ), ), child: Scaffold( backgroundColor: Colors.transparent, body: // 你的页面内容 ), ), );
这种方法会跟随系统主题自动切换,但如果需要支持用户手动切换主题(不依赖系统),你需要自己维护主题状态(比如用Provider或Riverpod)。
注意事项
- 确保你在
pubspec.yaml中正确声明了图片资源路径:
flutter: assets: - assets/light_background.png - assets/dark_background.png
- 若Scaffold有AppBar,也需要将AppBar的
backgroundColor设为透明或主题色的半透明值,避免遮挡背景图。
内容的提问来源于stack exchange,提问作者MNBLabs
相关产品推荐
相关产品推荐

