概述
- 主题风格
- 暗黑Theme适配
一、主题风格
Theme分为:全局Theme和局部Theme
主题有两个作用:
- 设置了主题之后,某些Widget会自动使用主题的样式(比如AppBar的颜色)
- 将某些样式放到主题中统一管理,在应用程序的其它地方直接引用
- 1.1. 全局Theme
全局Theme会影响整个app的颜色和字体样式。
使用起来非常简单,只需要向MaterialApp构造器传入 ThemeData 即可。
如果没有设置Theme,Flutter将会使用预设的样式。当然,我们可以对它进行定制。
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'FlutterDemo', // 正常模式 theme: ThemeData( // 1.亮度: light-dark,一般theme我们设置 light,在darkTheme里面设置dark brightness: Brightness.light, // 2.primarySwatch: primaryColor/accentColor的结合体 primarySwatch: Colors.red, // 3.主要颜色: 导航/底部TabBar primaryColor: Colors.blue, // 4.次要颜色: FloatingActionButton/按钮颜色 accentColor: Colors.brown, // 5.卡片主题 cardTheme: CardTheme( color: Colors.greenAccent, elevation: 10, shape: Border.all(width: 3, color: Colors.red), margin: EdgeInsets.all(10) ), // 6.按钮主题 buttonTheme: ButtonThemeData( minWidth: 0, height: 25 ), // 7.文本主题 textTheme: TextTheme( subtitle1: TextStyle(fontSize: 20), headline1: TextStyle(fontSize: 10), ), splashColor: Colors.transparent, // 点击的水波纹设置为无色 highlightColor: Colors.transparent ), // 暗黑模式 darkTheme: ThemeData( ), ); } }
- 1.2. 局部Theme
如果某个具体的Widget不希望直接使用全局的Theme,而希望自己来定义,只需要在Widget的父节点包裹一下Theme即可
创建另外一个新的页面,页面中使用新的主题:在新的页面的Scaffold外,包裹了一个Theme,并且设置data为一个新的ThemeData
class JKSecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return Theme( data: ThemeData(), child: Scaffold( ), ); } }
- 但是,我们很多时候并不是想完全使用一个新的主题,而且在之前的主题基础之上进行修改:
class HYSecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return Theme( data: Theme.of(context).copyWith( primaryColor: Colors.greenAccent ), child: Scaffold( ), ); } }
- 提示一:我们想要自己改的主题的内容可以在
Theme.of(context).copyWith( )
里面修改- 提示二:注意事项:
accentColor
在这里并不会被覆盖, 如果想要修改局部变量的 accentColor 我们可以如下做, secondary 才是修改的颜色,而 accentColor 是无效的
floatingActionButton: Theme( data: Theme.of(context).copyWith( colorScheme: Theme.of(context).colorScheme.copyWith( secondary: Colors.pink, ) ), child: FloatingActionButton( child: Icon(Icons.add), onPressed: () { }, ), ),
二. 暗黑Theme适配
- 2.1. darkTheme
目前很多应用程序都需要适配暗黑模式,Flutter中如何做到暗黑模式的适配呢?
事实上,MaterialApp中有theme和dartTheme两个参数:
按照下面的写法,我们已经默认适配了暗黑主题
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', // 正常的模式 theme: ThemeData.light(), // 暗黑模式 darkTheme: ThemeData.dark(), home: HYHomePage(), ); } }
- 2.2. 开发中适配在开发中,为了能适配两种主题(设置是更多的主题),我们可以封装一个AppTheme
- 1.公共的样式抽取成常量
- 2.封装一个亮色主题
- 3.封装一个暗黑主题
import 'package:flutter/material.dart'; class JKAppTheme { // 字体的设置 static const double smallFontSize = 12.0; static const double normalFontSize = 16.0; static const double largeFontSize = 22.0; // 颜色的设置 // 正常的颜色 static final Color normalTextColor = Colors.brown; // 暗黑模式的字体颜色 static final Color darkTextColor = Colors.yellow; // 正常的模式 static final ThemeData normalTheme = ThemeData( primaryColor: Colors.yellow, textTheme: TextTheme( subtitle1: TextStyle( fontSize: normalFontSize, color: normalTextColor ) ) ); // 暗黑模式 static final ThemeData darkTheme = ThemeData( primaryColor: Colors.yellow, textTheme: TextTheme( subtitle1: TextStyle( fontSize: normalFontSize, color: darkTextColor ) ) ); }
- 在MaterialApp中,可以决定使用哪一个主题:
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, home: HYHomePage(), ); } }
提示:MaterialApp 里面的title再iOS里面是没啥用的,在安卓了里面是有用的