上QQ阅读APP看书,第一时间看更新
2.3 Flutter主题
为了在整个应用中使用同一套颜色和字体样式,可以使用“主题”这种方式。定义主题有两种方式:全局主题,或使用Theme来定义应用程序局部的颜色和字体样式。事实上,全局主题只是由应用程序根MaterialApp创建的主题(Theme)。
定义一个主题后,就可以在我们自己的Widget中使用它,Flutter提供的Material Widgets将使用主题为AppBars、Buttons、Checkboxes等设置背景颜色和字体样式。
2.3.1 创建应用主题
创建主题的方法是将ThemeData提供给MaterialApp构造函数,这样就可以在整个应用程序中共享包含颜色和字体样式的主题。ThemeData的主要属性如表2-1所示。
表2-1 ThemeData属性及描述
如果没有提供主题,Flutter将创建一个默认主题。主题数据的示例代码如下:
new MaterialApp( title: title, theme: new ThemeData( brightness: Brightness.dark, primaryColor: Colors.lightBlue[800], accentColor: Colors.cyan[600], ), );
2.3.2 局部主题
如果我们想在应用程序的某一部分使用特殊的颜色,那么就需要覆盖全局的主题。有两种方法可以解决这个问题:创建特有的主题数据或扩展父主题。
1.创建特有的主题数据
实例化一个ThemeData并将其传递给Theme对象,代码如下:
new Theme(
//创建一个特有的主题数据
data: new ThemeData(
accentColor: Colors.yellow,
),
child: new FloatingActionButton(
onPressed: () {},
child: new Icon(Icons.add),
),
);
2.扩展父主题
扩展父主题时无须覆盖所有的主题属性,我们可以通过使用copyWith方法来实现,代码如下:
new Theme( //覆盖accentColor为Colors.yellow data: Theme.of(context).copyWith(accentColor: Colors.yellow), child: new FloatingActionButton( onPressed: null, child: new Icon(Icons.add), ), );
2.3.3 使用主题
主题定义好后就可以使用它了。首先,函数Theme.of(context)可以通过上下文来获取主题,方法是查找最近的主题,如果找不到就会找整个应用的主题。
下面来看一个简单的示例,应用的主题颜色定义为绿色,界面中间再加一个带有背景色的文本。
完整的例子代码如下所示:
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final appName = ’自定义主题’; return new MaterialApp( title: appName, theme: new ThemeData( brightness: Brightness.light, //应用程序整体主题的亮度 primaryColor: Colors.lightGreen[600], //App主要部分的背景色 accentColor: Colors.orange[600], //前景色(文本、按钮等) ), home: new MyHomePage( title: appName, ), ); } } class MyHomePage extends StatelessWidget { final String title; MyHomePage({Key key, @required this.title}) : super(key: key); @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(title), ), body: new Center( child: new Container( //获取主题的accentColor color: Theme.of(context).accentColor, child: new Text( '带有背景颜色的文本组件’, style: Theme.of(context).textTheme.title, ), ), ), floatingActionButton: new Theme( //使用copyWith的方式获取accentColor data: Theme.of(context).copyWith(accentColor: Colors.grey), child: new FloatingActionButton( onPressed: null, child: new Icon(Icons.computer), ), ), ); } }
自定义主题的效果如图2-1所示。
图2-1 自定义主题效果图