美文网首页
Flutter学习笔记34-主题

Flutter学习笔记34-主题

作者: zombie | 来源:发表于2020-12-23 11:16 被阅读0次

    Theme组件可以为Material APP定义主题数据(ThemeData)。Material组件库里很多组件都使用了主题数据,如导航栏颜色、标题字体、Icon样式等。Theme内会使用InheritedWidget来为其子树共享样式数据。

    ThemeData

    ThemeData用于保存是Material组件库的主题数据,Material组件需要遵守相应的设计规范,而这些规范可自定义部分都定义在ThemeData中了,所以可以通过ThemeData来自定义应用主题。在子组件中,可以通过Theme.of方法来获取当前的ThemeData
    ThemeData部分数据定义:

    ThemeData({
      Brightness brightness, // 深色还是浅色
      MaterialColor primarySwatch, // 主题颜色样本
      Color primaryColor, // 主色,决定导航栏颜色
      Color accentColor, // 次级色,决定大多数Widget的颜色,如进度条、开关等。
      Color cardColor, // 卡片颜色
      Color dividerColor, // 分割线颜色
      ButtonThemeData buttonTheme, // 按钮主题
      Color cursorColor, // 输入框光标颜色
      Color dialogBackgroundColor,// 对话框背景颜色
      String fontFamily, // 文字字体
      TextTheme textTheme,// 字体主题,包括标题、body等文字样式
      IconThemeData iconTheme, // Icon的默认样式
      TargetPlatform platform, // 指定平台,应用特定平台控件风格
      ...
    })
    

    代码示例:

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(
            // primarySwatch传入不是Color, 而是MaterialColor(包含了primaryColor和accentColor)
            primarySwatch: Colors.red,
            // primaryColor: 单独设置导航和TabBar的颜色
            primaryColor: Colors.orange,
            // accentColor: 单独设置FloatingActionButton、Switch等widget
            accentColor: Colors.green,
            // Button的主题
            buttonTheme: ButtonThemeData(
                height: 25, minWidth: 10, buttonColor: Colors.yellow),
            // Card的主题
            cardTheme: CardTheme(color: Colors.greenAccent, elevation: 10),
            // Text的主题
            textTheme: TextTheme(
              bodyText2: TextStyle(fontSize: 16, color: Colors.red),
              bodyText1: TextStyle(fontSize: 20, color: Colors.blue),
              headline1: TextStyle(fontSize: 14),
              headline2: TextStyle(fontSize: 16),
              headline3: TextStyle(fontSize: 18),
              headline4: TextStyle(fontSize: 20),
            ),
          ),
          home: ThemeDemo(),
        );
      }
    }
    
    class ThemeDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("首页")),
          body: Center(
            child: Column(
              children: <Widget>[
                Text("Hello World"),
                Text(
                  "Hello World",
                  style: TextStyle(fontSize: 14),
                ),
                Text(
                  "Hello World",
                  style: TextStyle(fontSize: 20),
                ),
                Text(
                  "Hello World",
                  style: Theme.of(context).textTheme.bodyText1,
                ),
                Text(
                  "Hello World",
                  style: Theme.of(context).textTheme.headline3,
                ),
                Switch(
                  value: true,
                  onChanged: (value) {},
                ),
                CupertinoSwitch(
                  value: true,
                  onChanged: (value) {},
                  activeColor: Colors.red,
                ),
                RaisedButton(
                  child: Text("R"),
                  onPressed: () {},
                ),
                Card(
                  child: Text(
                    "Hello,Smile",
                    style: TextStyle(fontSize: 50),
                  ),
                )
              ],
            ),
          ),
          bottomNavigationBar: BottomNavigationBar(
            items: [
              BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),
              BottomNavigationBarItem(label: '分类', icon: Icon(Icons.category))
            ],
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (ctx) {
                    return SecondPage();
                  },
                ),
              );
            },
          ),
        );
      }
    }
    

    代码运行效果图如下:


    效果图

    如果某个具体的Widget不希望直接使用全局的Theme,而希望自己来定义,只需要在Widget的父节点包裹一下Theme即可。创建另外一个新的页面,页面中使用新的主题:在新的页面的Scaffold外,包裹了一个Theme,并且设置data为一个新的ThemeData,代码示例:

    class SecondPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Theme(
          data: Theme.of(context).copyWith(primaryColor: Colors.purple),
          child: Scaffold(
            appBar: AppBar(
              title: Text("第二页"),
              backgroundColor: Colors.purple,
            ),
            body: Center(
              child: Text("Second Page"),
            ),
            floatingActionButton: Theme(
              data: Theme.of(context).copyWith(
                colorScheme:
                    Theme.of(context).colorScheme.copyWith(secondary: Colors.pink),
              ),
              child: FloatingActionButton(
                child: Icon(Icons.pets),
                onPressed: () {},
              ),
            ),
          ),
        );
      }
    }
    

    代码运行效果图如下:


    效果图

    这里有一个注意事项:accentColor在这里并不会被覆盖。需要使用:

    Theme.of(context).copyWith
    (
       colorScheme:Theme.of(context).colorScheme.copyWith(secondary: Colors.pink),
    )
    

    代码传送门

    相关文章

      网友评论

          本文标题:Flutter学习笔记34-主题

          本文链接:https://www.haomeiwen.com/subject/fclynktx.html