Flutter 核心技术与实战
陈航
前美团点评高级技术专家
42432 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
Flutter 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

16 | 从夜间模式说起,如何定制不同风格的App主题?

根据defaultTargetPlatform,配置对应的主题
使用Theme.of方法取出主题对应的属性值,实现多种组件在视觉风格上的复用
通过Theme单子Widget容器使用局部主题覆盖全局主题,实现局部独立的视觉风格
可以通过设置MaterialApp全局主题实现应用整体视觉风格的统一
主题设置提供了一种视觉资源与配置的管理机制
为iOS与Android分别创建不同的主题
根据defaultTargetPlatform判断当前应用所运行的平台
主题的重要用途是样式复用
定义新的ThemeData实例或继承App的主题
使用Theme对App的主题进行局部覆盖
精确控制展示样式需要细化主题配置
修改主题参数会影响其他次级视觉属性
MaterialApp的初始化方法提供设置主题的能力
主题管理和切换
主题切换只是更新资源及配置集合
主题由颜色、图片、字号、字体等组成
总结
分平台主题定制
局部独立的视觉风格定制
全局统一的视觉风格定制
主题定制
Flutter中实现切换主题的功能需要做的事情
实现应用内切换样式的功能
主题样式更换是实现个性化的重要技术手段
通过用户分层实现App的个性化
处理基本功能有和无的问题
组装与自绘两种自定义Widget的方式
从夜间模式说起,如何定制不同风格的App主题

该思维导图由 AI 生成,仅供参考

你好,我是陈航。今天,我和你分享的主题是,从夜间模式说起,如何定制不同风格的 App 主题。
在上一篇文章中,我与你介绍了组装与自绘这两种自定义 Widget 的方式。对于组装,我们按照从上到下、从左到右的布局顺序去分解目标视图,将基本的 Widget 封装到 Column、Row 中,从而合成更高级别的 Widget;而对于自绘,我们则通过承载绘制逻辑的载体 CustomPainter,在其 paint 方法中使用画笔 Paint 与画布 Canvas,绘制不同风格、不同类型的图形,从而实现基于自绘的自定义组件。
对于一个产品来说,在业务早期其实更多的是处理基本功能有和无的问题:工程师来负责实现功能,PM 负责功能好用不好用。在产品的基本功能已经完善,做到了六七十分的时候,再往上的如何做增长就需要运营来介入了。
在这其中,如何通过用户分层去实现 App 的个性化是常见的增长运营手段,而主题样式更换则是实现个性化中的一项重要技术手段。
比如,微博、UC 浏览器和电子书客户端都提供了对夜间模式的支持,而淘宝、京东这样的电商类应用,还会在特定的电商活动日自动更新主题样式,就连现在的手机操作系统也提供了系统级切换展示样式的能力。
那么,这些在应用内切换样式的功能是如何实现的呢?在 Flutter 中,在普通的应用上增加切换主题的功能又要做哪些事情呢?这些问题,我都会在今天的这篇文章中与你详细分享。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Flutter主题定制是App开发中的重要特性,本文介绍了如何在Flutter中定制不同风格的App主题,从夜间模式说起。作者首先介绍了主题定制的概念,将主题视为视觉效果在不同场景下的可视资源和相应的配置集合。在iOS、Android和前端中,主题的配置信息通常预先写入文件或属性值中,通过单例或特定方法进行切换。而在Flutter中,可以使用ThemeData来统一管理主题的配置信息。通过ThemeData,可以实现全局范围和局部范围的样式切换。全局统一的视觉风格定制可以通过MaterialApp的初始化方法来设置主题,而局部独立的视觉风格定制可以使用Theme来对App的主题进行局部覆盖。此外,主题的另一个重要用途是样式复用,可以通过Theme.of(context)方法取出对应的属性,应用到子Widget的样式中。文章通过示例代码演示了如何在Flutter中实现主题的定制和切换,帮助读者快速了解了主题定制的基本概念和实现方法。除了主题之外,读者还可以利用defaultTargetPlatform变量实现一些其他需要判断平台的逻辑,比如在界面上使用更符合Android或iOS设计风格的组件。文章最后给出了思考题,鼓励读者在评论区分享观点,为读者提供了进一步学习的机会。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Flutter 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(15)

  • 最新
  • 精选
  • dao
    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]); } }

    作者回复: 赞

    2019-08-10
    2
    12
  • 灰灰
    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
    2
    5
  • Ω
    defaultTargetPlatform这个变量哪里来的,文章中没有说明清楚

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

    2019-08-05
    2
  • 小米
    思考题: 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-05
    2
  • 文心雕龙
    第三方插件 https://pub.dev/packages/dynamic_theme#-readme-tab-

    作者回复: 赞

    2019-08-06
    1
  • 菜头
    Theme.of(context) 方法将向上查找 Widget 树,并返回 Widget 树中最近的主题 Theme。如果 Widget 的父 Widget 们有一个单独的主题定义,则使用该 Theme 如果不是,就使用 App 全局 Theme。 这个表示没太懂。 最近?是表示其第一个 superWidget 吗? 父 Widget 们?一个 widget 有多个父 widget?

    作者回复: 父Widget们=祖先

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

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

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

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

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

    作者回复: 对,会覆盖

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

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

    2019-08-06
    2
收起评论
显示
设置
留言
15
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部