• dao
    2019-08-10
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';

    void main() => runApp(MyThemePage());

    class MyThemePage extends StatelessWidget {
      // iOS 浅色主题
      final ThemeData kIOSTheme = ThemeData(
          brightness: Brightness.light,
          accentColor: Colors.white,
          primaryColor: Colors.blue,
          iconTheme: IconThemeData(color: Colors.grey),
          textTheme: TextTheme(body1: TextStyle(color: Colors.black)));

      // Android 深色主题
      final ThemeData kAndroidTheme = ThemeData(
          brightness: Brightness.dark, // 深色主题
          accentColor: Colors.black, //(按钮)Widget 前景色为黑色
          primaryColor: Colors.cyan, // 主题色为青色
          iconTheme: IconThemeData(color: Colors.blue), //icon 主题色为蓝色
          textTheme: TextTheme(body1: TextStyle(color: Colors.red)) // 文本主题色为红色
          );

      Widget build(BuildContext context) {
        var theme = MyTheme(
          title: 'Flutter Demo Home Page',
          themes: [kIOSTheme, kAndroidTheme],
        );
        return MaterialApp(
          title: 'My Theme',
          theme: kAndroidTheme,
          home: theme,
        );
      }
    }

    class MyTheme extends StatefulWidget {
      MyTheme({Key key, this.title, this.themes}) : super(key: key);

      final String title;
      final List<ThemeData> themes;

      _MyThemeState createState() => _MyThemeState();
    }

    class _MyThemeState extends State<MyTheme> {
      bool isLight;

      @override
      void initState() {
        isLight = true;
        super.initState();
      }

      @override
      Widget build(BuildContext context) {
        return Theme(
            child: Scaffold(
              appBar: AppBar(
                title: Text('Theme switch'),
              ),
              floatingActionButton: FloatingActionButton(
                child: Text(isLight ? 'Night' : 'Light'),
                onPressed: () {
                  setState(() {
                    isLight = !isLight;
                  });
                },
              ),
            ),
            data: isLight ? widget.themes[0] : widget.themes[1]);
      }
    }
    展开

    作者回复: 赞

     1
     4
  • jianwei
    2020-01-07
    在全局的theme中定义多个 textTheme: TextTheme(body1: TextStyle(color: Colors.grey), body2: TextStyle(color: Colors.white), ...),然后内部widget按需加载相应的 theme.body1 or theme.body2
    
    
  • 菜头
    2019-11-15
    Theme.of(context) 方法将向上查找 Widget 树,并返回 Widget 树中最近的主题 Theme。如果 Widget
    的父 Widget 们有一个单独的主题定义,则使用该 Theme
    如果不是,就使用 App 全局 Theme。

    这个表示没太懂。
    最近?是表示其第一个 superWidget 吗?
    父 Widget 们?一个 widget 有多个父 widget?


    展开

    作者回复: 父Widget们=祖先

    
    
  • zzz
    2019-10-23
    请问下,目前主流的App内UI的样式应该不会局限于ThemeData中的定义的情况。比如有一个自定义的Button,是在代码中设置的特殊Color,不是Themedata里的,这种情况下的button(或类似实现的全部widget),对于日夜间切换这种动态处理的时候,有统一的换颜色的方法么?还是需要在每个widget中都要实现对应的颜色处理?同样的对于TextTheme,ThemeData只提供了textTheme,primaryTextTheme,accentTextTheme三种,如果App内有更多的通用TextTheme,如何动态的统一切换呢?

    作者回复: 你可以自己抽象出一套属性配置,控制的粒度更细一些,通过开关统一切换,本质上和系统主题类似

    
    
  • 🌝
    2019-09-20
    如果全局更改主题的话,那岂不是要把MaterialApp这个Widget设置成有状态的widget?这样子是不是更耗性能

    作者回复: 是啊,换主题本身就相当于重建整个App的UI了,自然需要重走一遍根视图的生命周期

    
    
  • 和小胖
    2019-09-04
    老师,这个全局主题的设置只是针对于布局中的对应 widget 没有设置样式才会生效吧?例如我在 ThemeData 里面设置了文字颜色为黑色?但是我在子 widget 里面设置了一个文字会红色,那么此时黑色是不生效的吧?

    作者回复: 对,会覆盖

    
    
  • 灰灰
    2019-08-06
    class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
      TabController _controller;
      bool isNight = false;
      @override
      void initState() {
        super.initState();
        _controller = TabController(length: 2, vsync: this);
      }

      @override
      Widget build(BuildContext context) {
        return
          Theme(
            data: ThemeData(
              brightness: isNight ? Brightness.dark : Brightness.light,
            ),
            child: Stack(
              children: <Widget>[
                Scaffold(
                  ...
                ),
                Positioned(
                  bottom: 20,
                  right: 20,
                  child: FloatingActionButton(
                    onPressed: () {setState(() {
                      isNight = !isNight;
                    });},
                    child: Text(isNight ? '日间' : '夜间'),
                  ),
                )
              ],
            ),
          );
      }

      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    }
    展开

    作者回复: 赞

    
    
  • 文心雕龙
    2019-08-06
    第三方插件 https://pub.dev/packages/dynamic_theme#-readme-tab-

    作者回复: 赞

    
    
  • 宋世通
    2019-08-06
    老师,在flutter1.8.2,1.8.3版本中增加了ThemeMode,是不是用这个来控制主题明暗会更好一点?

    作者回复: 可以的。ThemeMode是在主题之上,是用来设置是否跟随系统设置的属性,你可以通过它来强制设置App主题为明或暗,也可以跟随系统,这样就需要把两套主题都实现了

     1
    
  • Ω
    2019-08-05
    defaultTargetPlatform这个变量哪里来的,文章中没有说明清楚

    作者回复: import 'package:flutter/foundation.dart';

    
    
  • 小米
    2019-08-05
    思考题:
    1、增加一个布尔变量
          bool _isLight = false
    2、在ThemeData中,根据_isLight来显示是否为高亮或者暗色。
          brightness: _isLight ? Brightness.light : Brightness.dark
    3、增加一个切换按钮,点击改变_isLight值。
          FlatButton(onPressed: (){setState(() { _isLight = !_isLight; });},child: Text(_isLight?"白天":"夜间"))
    展开

    作者回复: 赞

    
    
  • 许童童
    2019-08-03
    老师你好,这个Theme应该是要定义为状态,在setState里面修改这个变量,但是代码不知道怎么写,老师能否给一下代码。

    作者回复: 可以参考小米同学的实现

     1
    
我们在线,来聊聊吧