【问题标题】:How to change theme of the entire app using 3 different themes (Flutter)如何使用 3 个不同的主题更改整个应用程序的主题 (Flutter)
【发布时间】:2019-09-06 22:47:54
【问题描述】:

在这个应用程序中有三个不同的主题 - 红色、黑色和白色。从主屏幕,用户可以导航到主题屏幕,在那里他们可以选择特定的主题。我想使用一种方法,该方法将使用返回 ThemeData 的类中的函数或构造函数,并将其发送到 MaterialApp 中的 theme: main.dart

这是一种有效的方法吗?如果是,那么我能否获得有关如何在MaterialApp 上正确设置主题的指南。 如果没有,我能否就如何在此应用中设置三个主题提出一些建议。

这是我试图作为构造函数传递并设置特定背景主题颜色的类:

class ThemeChooser extends StatelessWidget {
  static int color;
  ThemeData data = ThemeData(scaffoldBackgroundColor: Color(color));
  ThemeChooser({color});
  @override
  Widget build(BuildContext context) {
    return ThemeChooser(color: color,);
  }
}

这是选择主题的按钮(这只是一个按钮,但假设还有两个用于设置黑白主题):

    FlatButton(
               onPressed: ()async {
               final result = await Navigator.push(
               context,
               MaterialPageRoute( 
                 builder: (context) => ThemeScreen(),                              
                             ));
                          setState(() {
                            setThemeRed(redcolor);
                          });
                        },
                        child: Padding(
                          padding: const EdgeInsets.only(top: 40, left: 8),
                          child: whitefontstyle(text: "Red", size: 50,),
                        )
                    ),

这是使用ThemeChooser 的构造函数来设置主题的方法(我只将设置声明为红色主题atm。):


int color;

setThemeRed(int color){
  return ThemeChooser(color: redcolor,);
}

这是主要方法:

void main(){
  runApp(MaterialApp(
// the theme below also needs to take the value in ThemeChooser set in ThemeScreen.

//    theme: 
    home: TodoList(),
  ));
}

【问题讨论】:

    标签: flutter themes


    【解决方案1】:

    每次更改主题时,您都必须重新构建材质应用程序。所以你可以使用 BLoC 来做到这一点。

    class ThemeBloc{
       final _themeController = StreamController<ThemeData>.broadcast();
       Sink<ThemeData> get inputter => _themeController.sink;
       Stream<ThemeData> get outputter => _themeController.stream;
    
      ThemeBloc(){
      // when the app loads put the initial themeData that 
      //you want to show
       inputter.add(initialThemeData); 
       }
    
       //use this to dispose the controller whenever the app gets closed
       void dispose(){
          _themeController.close();
       }
    
    }
    

    现在使用 StreamBuilder 来包装 MaterialApp,

      ThemeBloc _bloc = ThemeBloc();
      @override
      Widget build(BuildContext context) {
        return StreamBuilder<ThemeData>(
          stream: bloc.outputter,
          initialData: defaultThemeData,
          builder: (context, snapshot) => MaterialApp(
                home: ToDoList(),
                theme: snapshot.data,// this is the themeData that we're getting from the 
                                     //stream
              ),
        );
      }
    

    现在我们如何改变主题?

      //let's say we have a button that would change the theme,
      RaisedButton(){
        onPressed: (){
        inputter.add(redTheme); // redTheme is a ThemeData that you must give,
        },
        child: Text("Enable Red Theme")
      }
    

    我还没有测试过代码,但它应该可以工作!

    【讨论】:

    • 在主题屏幕上更改主题时,此方法是否会从“主题”屏幕更改主题,而不会一直折叠回主屏幕?
    • 它将改变应用程序的整个主题。但是现在 pub.dev 中有很多库可以轻松更改主题。你可以改用这些。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    相关资源
    最近更新 更多