质感设计的Theme
类将主题应用于后代控件,主题描述了应用程序的颜色和排版选择。后代控件使用Theme.of
获取当前主题的ThemeData
对象,当控件使用Theme.of
时,如果主题稍后更改,则会自动重建,以便可以应用更改。我们可以通过Theme.of
查看当前应用程序的配色方案。
class _MyHomePageState extends State<MyHomePage> {
Widget _colorDisplayBox(String explanation, String name, Color color) {
return new Column(
children: <Widget>[
new Row(
children: <Widget>[
new Text("$explanation\n$name\t\t"),
new Flexible(
child: new Container(
height: 30.0, decoration: new BoxDecoration(color: color)))
],),
new Divider()
],);}
@override
Widget build(BuildContext context) {
return new Scaffold(
//...
body: new Center(
child: new ListView(
padding: new EdgeInsets.all(8.0),
children: <Widget>[
_colorDisplayBox("突出颜色", "highlightColor", Theme.of(context).highlightColor),
_colorDisplayBox("提示颜色", "hintColor", Theme.of(context).hintColor),
_colorDisplayBox("文本选择手柄颜色", "textSelectionHandleColor", Theme.of(context).textSelectionHandleColor),
_colorDisplayBox("文字选择颜色", "textSelectionColor", Theme.of(context).textSelectionColor),
_colorDisplayBox("背景颜色", "backgroundColor", Theme.of(context).backgroundColor),
_colorDisplayBox("强调颜色", "accentColor", Theme.of(context).accentColor),
_colorDisplayBox("画布颜色", "canvasColor", Theme.of(context).canvasColor),
_colorDisplayBox("卡片颜色", "cardColor", Theme.of(context).cardColor),
_colorDisplayBox("按钮颜色", "buttonColor", Theme.of(context).buttonColor),
_colorDisplayBox("对话框背景颜色", "dialogBackgroundColor", Theme.of(context).dialogBackgroundColor),
_colorDisplayBox("禁用颜色", "disabledColor", Theme.of(context).disabledColor),
_colorDisplayBox("分频器颜色", "dividerColor", Theme.of(context).dividerColor),
_colorDisplayBox("错误颜色", "errorColor", Theme.of(context).errorColor),
_colorDisplayBox("指示灯颜色", "indicatorColor", Theme.of(context).indicatorColor),
_colorDisplayBox("原色", "primaryColor", Theme.of(context).primaryColor),
_colorDisplayBox("脚手架背景颜色", "scaffoldBackgroundColor", Theme.of(context).scaffoldBackgroundColor),
_colorDisplayBox("次标头颜色", "secondaryHeaderColor", Theme.of(context).secondaryHeaderColor),
_colorDisplayBox("选择行颜色", "selectedRowColor", Theme.of(context).selectedRowColor),
_colorDisplayBox("飞溅颜色", "splashColor", Theme.of(context).splashColor),
_colorDisplayBox("未选择的控件颜色", "unselectedWidgetColor", Theme.of(context).unselectedWidgetColor),
],),),);}}
我们可以自定义配色,比如设置primaryColor
为红色。还可以使用primaryColorBrightness
设置primaryColor
的亮度,用于设置放置在原色顶部的文本和图标的颜色。
需要注意这里的亮度是描述颜色的对比度需求,有两个常量。Brightness.dark
表示颜色很暗,需要浅色文字颜色才能实现可读性,例如颜色可能是深灰色,需要白色文字。Brightness.light
表示颜色很浅,需要深色文字颜色来实现可读性,例如颜色可能是明亮的白色,需要黑色文字。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primaryColor: Colors.red,
primaryColorBrightness: Brightness.dark,
),
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
我们还可以根据不同平台设置主题,比如我们在iOS上设置白色和灰色主题,在Android上设置紫色和橙色主题。判断平台类型需要使用defaultTargetPlatform
来识别当前系统平台,然后根据平台类型设置主题。
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() {
runApp(new MyApp());
}
final ThemeData kIOSTheme = new ThemeData(
primarySwatch: Colors.orange,
primaryColor: Colors.grey[100],
primaryColorBrightness: Brightness.light,
);
final ThemeData kDefaultTheme = new ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.orangeAccent[400],
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: defaultTargetPlatform == TargetPlatform.iOS
? kIOSTheme
: kDefaultTheme,
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
在上面的代码中,有一段大家可能有疑问:primarySwatch: Colors.orange
。颜色(Color)是ARGB格式的不可变的32位颜色值,具有相关颜色的小表的颜色称为样本(Swatch),颜色和样本的常量,表示质感设计的调色板。
大多数色板的颜色从100到900,增量为100,加上颜色50。数字越小,颜色越浅,数字越大,颜色越暗。强调色调(例如redAccent)只有数值100、200、400和700。
此外,还有一系列具有普遍不透明度的黑色和白色。例如,black54是具有54%不透明度的纯黑色。
要从其中一个色板中选择特定颜色,需要使用所需特定颜色的整数索引到样本。每个颜色样本常量是一种颜色,可以直接使用。
Color selection = Colors.green[400];
new Container(
color: Colors.blue,
)
关于更多调色板,可以访问Flutter API的相关文档进一步了解。