Flutter学习笔记34-主题

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),
)

代码传送门

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341