Flutter:如何在运行时更改主题亮度?

时间:2019-01-11 03:17:18

标签: flutter material-design

我有一个MaterialApp,其中一个ThemeData最初设置为Brightness.light。我想在运行时将亮度切换为Brightness.dark,但是当我进行更改时,只有状态栏会更改-Flutter小部件实际上没有更改其亮度。

如何实现这种行为?

要在运行时更改ThemeData,我创建了以下StatefulWidget,该MaterialApp包装了final ThemeData appTheme = ThemeData( brightness: Brightness.light, ); class ThemeChanger extends StatefulWidget { static ThemeChangerState of (BuildContext context) { return context.ancestorStateOfType(TypeMatcher<ThemeChangerState>()); } ThemeChanger({ this.childBuilder, }); final Widget Function(BuildContext, ThemeData) childBuilder; @override ThemeChangerState createState() => ThemeChangerState(); } class ThemeChangerState extends State<ThemeChanger> { Brightness _brightness = Brightness.light; set brightness(Brightness brightness) { setState(() { _brightness = brightness; }); } @override Widget build(BuildContext context) { return widget.childBuilder( context, appTheme.copyWith( brightness: _brightness ), ); } } // Then in main.dart void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return DemoTheme( childBuilder: (BuildContext context, ThemeData theme) { return MaterialApp( title: 'Materially Better', theme: theme, routes: { '/': (BuildContext context) { return LoginScreen(); }, 'home': (BuildContext context) { return MainScreen(); } }, debugShowCheckedModeBanner: false, ); }, ); } } 并在主题更改时重新构建它:

ThemeData

4 个答案:

答案 0 :(得分:2)

问题是brightness在构造函数中使用其ThemeData值来合成许多其他颜色,但是当ThemeData发生突变时,这些颜色不会重新计算。因此,解决方案是实例化全新的appTheme.copyWith(...)而不是使用appTheme.copyWith( brightness: _brightness, ),

更改此:

ThemeData(
  brightness: _brightness,
),

对此:

#/usr/bin/env sh
echo -e "What VM?"
read vname
if [ '`VboxManage list vms | grep -c "$vname"`' != 0 ]; then
    echo exists
fi

答案 1 :(得分:1)

我的解决方法是:

  1. main.dart中为亮度定义一个变量,并更改状态的函数。

  2. 将函数传递给类,然后在需要的地方调用它。

//main.dart
class _MyAppState extends State<MyApp> {
  Brightness _brightness = Brightness.light;

  void _changeBrightness(Brightness newBrightness) {
    setState(() {
      _brightness = newBrightness;
    });
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      //PASSING THE FUNCTION AS PARAMETER
      Util.changeBrightness = _changeBrightness;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Your app title',
      theme: ThemeData(
        primaryColor: const Color(0xFFb30047),
        brightness: _brightness,
        primarySwatch: Colors.blue,
        accentColor: Colors.white,
        /// ...and so on

Util类中

class Util {
   static Brightness currentBrightness = Brightness.light;
   static Function changeBrightness;
   // ...further implementations

然后在需要时调用它。就我而言,设置屏幕中的开关发生了变化:

darkModeChanged(bool newValue) {
   Preferences.setBool('darkMode', newValue);
   setState(() {
     _darkMode = newValue;
     Util.currentBrightness = _darkMode ? Brightness.dark : Brightness.light;        
     Util.changeBrightness(Util.currentBrightness);
   });
}

答案 2 :(得分:0)

您可以签出以下库:https://github.com/Norbert515/dynamic_theme

它允许您在运行时动态更改整个主题数据或应用程序的亮度。

答案 3 :(得分:0)

您可以在运行时使用ThemeBuilder更改主题:

setState(() {
  ThemeBuilder.of(context).changeTheme();
});
相关问题