App主題色控制
-
Theme有兩種:全局
Theme
和局部Theme
。全局Theme
是由應用程序根MaterialApp
建立的Theme 。web -
Theme做用:能夠設置
Widget
的主題,提升開發效率和速度,保持App主題統一性或某種一致性。canvas
Theme
Theme
組件能夠爲material
APP
定義主題數據(ThemeData
)。Material
組件庫裏不少組件都使用了主題數據, 如導航欄顏色、標題字體、Icon
樣式等。Theme內會使用InheritedWidget
來爲其子樹共享樣式數據。數組
設置主題栗子
全局:
/// 全局主題在MaterialApp的theme屬性
/// 全局生效
new MaterialApp(
title: 'demo',
theme: new ThemeData( // 這裏就是參數
brightness: Brightness.dark,
primaryColor: Colors.lightBlue[800],
accentColor: Colors.cyan[600],
),
);
局部:
/// 假如咱們要給FloatingActionButton設置主題樣式
/// 直接寫個Theme包裹FloatingActionButton組件
/// 而後設置data,接收類型依然是ThemeData,裏面填寫咱們的參數
/// (若是沒有設置局部主題則默認使用全局主題)
new Theme(
data: new ThemeData(
accentColor: Colors.yellow,
),
child: new FloatingActionButton(
onPressed: () {},
child: new Icon(Icons.add),
),
);
擴展父主題:
/// 擴展父主題時無需覆蓋全部的主題屬性,能夠經過使用copyWith方法來實現
new Theme(
data: Theme.of(context).copyWith(accentColor: Colors.yellow),
child: new FloatingActionButton(
onPressed: null,
child: new Icon(Icons.add),
),
);
Theme.of(context)
將查找Widget樹並返回樹中最近的Theme。若是Widget之上有一個單獨的Theme定義, 則返回該值。若是不是,則返回App主題。微信
判斷平臺顯示指定主題:
/// defaultTargetPlatform在foundation包裏。
///
/// 咱們也可使用io包裏的Platform來進行判斷。
/// 那麼判斷就是
/// theme: Platform.isIOS ? iOSTheme : AndroidTheme,
new MaterialApp(
theme: defaultTargetPlatform == TargetPlatform.iOS
? iOSTheme
: AndroidTheme,
title: 'Flutter Theme',
home: new MyHomePage(),
);
Tips:
Flutter的Color中大多數顏色從100到900,增量爲100,加上顏色50,數字越小顏色越淺, 數字越大顏色越深。強調色調只有100、200、400和700。markdown
栗子:
推薦站點(Material design):
https://material.io/resources/color,app
爲你的UI建立共享調色板,並衡量任何顏色組合的可觀性【很是實用的工具】。less
ThemeData(Color類型屬性):
-
accentColor - 前景色(文本、按鈕等) -
backgroundColor - 與 primaryColor
對比的顏色(例如 用做進度條的剩餘部分)。 -
bottomAppBarColor - BottomAppBar
的默認顏色。 -
buttonColor - Material
中RaisedButtons
使用的默認填充色。 -
canvasColor - MaterialType.canvas Material
的默認顏色。 -
cardColor - Material
被用做Card
時的顏色。 -
dialogBackgroundColor - Dialog
元素的背景色。 -
disabledColor - 用於 Widget
無效的顏色,不管任何狀態。例如禁用複選框。 -
dividerColor - Dividers和PopupMenuDividers
的顏色,也用於ListTiles
中間,和DataTables的每行中間. -
errorColor - 用於輸入驗證錯誤的顏色,例如在 TextField
中。 -
highlightColor - 用於相似墨水噴濺動畫或指示菜單被選中的高亮顏色。 -
hintColor - 用於提示文本或佔位符文本的顏色,例如在 TextField
中。 -
indicatorColor - TabBar
中選項選中的指示器顏色。 -
primaryColor - App主要部分的背景色( ToolBar
,TabBar
等)。 -
primaryColorDark - primaryColor
的較暗版本。 -
primaryColorLight - primaryColor
的較亮版本。 -
scaffoldBackgroundColor - 做爲 Scaffold
基礎的Material
默認顏色,典型Material
應用或應用內頁面的背景顏色。 -
secondaryHeaderColor - 有選定行時 PaginatedDataTable
標題的顏色。 -
selectedRowColor - 選中行時的高亮顏色。 -
splashColor - 墨水噴濺的顏色。 -
textSelectionColor - 文本字段中選中文本的顏色,例如 TextField
。 -
textSelectionHandleColor - 用於調整當前文本的哪一個部分的句柄顏色。 -
toggleableActiveColor - 用於突出顯示切換 Widget
(如Switch
,Radio
和Checkbox
)的活動狀態的顏色。 -
unselectedWidgetColor - 用於 Widget
處於非活動(但已啓用)狀態的顏色。例如,未選中的複選框。一般與accentColor
造成對比。 -
focusColor - 焦點獲取時的顏色,例如,一些按鈕焦點、輸入框焦點。 -
hoverColor - 點擊以後徘徊中的顏色,例如,按鈕長按,按住以後的顏色。 -
cursorColor - 輸入框光標顏色。
ThemeData(Theme相關類型屬性):
-
accentIconTheme - IconThemeData
類型,與突出顏色對照的圖片主題。 -
accentTextTheme - TextTheme
類型,與突出顏色對照的文本主題。 -
chipTheme - ChipThemeData
類型,用於渲染Chip
的顏色和樣式。 -
buttonTheme - ButtonThemeData
類型,定義了按鈕等控件的默認配置,像RaisedButton
和FlatButton
。 -
primaryIconTheme - IconThemeData
類型,一個與主色對比的圖片主題。 -
primaryTextTheme - TextThemeData
類型,一個與主色對比的文本主題。 -
iconTheme - IconThemeData
類型,與卡片和畫布顏色造成對比的圖標主題。 -
inputDecorationTheme - InputDecorationTheme
類型,InputDecorator
,TextField
和TextFormField
的默認InputDecoration
值基於此主題。 -
sliderTheme - SliderThemeData
類型,用於渲染Slider
的顏色和形狀。 -
textTheme - TextTheme
類型,與卡片和畫布對比的文本顏色。 -
toggleButtonsTheme - ToggleButtonsThemeData
類型,Flutter 1.9 全新組件ToggleButtons
的主題。 -
tabBarTheme - TabBarTheme
類型,TabBar
的主題樣式。 -
tooltipTheme - TooltipThemeData
類型,tooltip
提示的主題樣式。 -
cardTheme - CardTheme
類型,卡片的主題樣式。 -
pageTransitionsTheme - PageTransitionsTheme
類型,頁面轉場主題樣式。 -
appBarTheme - AppBarTheme
類型,AppBar
主題樣式。 -
bottomAppBarTheme - BottomAppBarTheme
類型,底部導航主題樣式。 -
dialogTheme - DialogTheme
類型,對話框主題樣式。 -
floatingActionButtonTheme - FloatingActionButtonThemeData
類型,FloatingActionButton
的主題樣式,也就是Scaffold
屬性的那個。 -
cupertinoOverrideTheme - CupertinoThemeData
類型,cupertino
覆蓋的主題樣式。 -
snackBarTheme - SnackBarThemeData
類型,彈出的snackBar
的主題樣式。 -
bottomSheetTheme - BottomSheetThemeData
類型,底部滑出對話框的主題樣式。 -
popupMenuTheme - PopupMenuThemeData
類型,彈出菜單對話框的主題樣式。 -
bannerTheme - MaterialBannerThemeData
類型,Material
材質的Banner
主題樣式。 -
dividerTheme - DividerThemeData
類型,Divider
組件的主題樣式,也就是那個橫向線條組件。
ThemeData(其餘類型屬性):
-
accentColorBrightness - Brightness
類型,accentColor
的亮度。用於肯定放置在突出顏色頂部的文本和圖標的顏色(例如FloatingButton
上的圖標)。 -
brightness - Brightness
類型,應用程序總體主題的亮度。由按鈕等Widget
使用,以肯定在不使用主色或強調色時要選擇的顏色。 -
platform - TargetPlatform
類型,Widget
須要適配的目標類型。 -
splashFactory - InteractiveInkFeatureFactory
類型,定義InkWall
和InkResponse
生成的墨水噴濺的外觀。 -
primaryColorBrightness - Brightness
類型,primaryColor
的亮度。 -
fontFamily - String
類型,字體樣式。 -
applyElevationOverlayColor bool
類型,是否應用elevation
覆蓋顏色。 -
materialTapTargetSize - MaterialTapTargetSize
類型,Chip
等組件的尺寸主題設置,如:設置爲MaterialTapTargetSize.shrinkWrap
時,clip
距頂部距離爲0;設置爲MaterialTapTargetSize.padded
時距頂部有一個距離 -
colorScheme - ColorScheme
類型,scheme組顏色,一組13種顏色,可用於配置大多數組件的顏色屬性。 -
typography - Typography
類型,用於配置TextTheme
、primaryTextTheme
和accentTextTheme
的顏色和幾何文本主題值。
適配夜間模式
實現效果:
分析:
此次是使用局部的實現,哪一個頁面須要同步就加個Theme就好了,全局也是相似的實現方式,主體代碼不到100行。編輯器
代碼:
首先寫個配置類,主要配置主題的是否爲黑夜模式和主題樣式:ide
class Config {
static bool dark = true; // 是否爲黑夜模式
static ThemeData themeData = new ThemeData.dark(); // 主題爲暗色
}
而後咱們正常的執行代碼:工具
import 'package:flutter/material.dart';
import 'global_config.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(title: "Flutter高級進階", home: new MyScaffold());
}
}
class MyScaffold extends StatefulWidget {
@override
_MyScaffoldState createState() => _MyScaffoldState();
}
class _MyScaffoldState extends State<MyScaffold> {
/*
* 主題改變
* */
changeTheme() {
if (Config.dark) {
Config.themeData = new ThemeData(
primaryColor: Colors.white,
scaffoldBackgroundColor: new Color(0xFFEBEBEB),
);
Config.dark = false;
} else {
Config.themeData = new ThemeData.dark();
Config.dark = true;
}
setState(() {});
}
Widget body(context) {
return new ListView(
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width / 4, // 整寬除4
child: new GestureDetector(
onTap: () => changeTheme(), // 觸發更換主題的事件
child: new Column(
children: <Widget>[
new FlutterLogo(
size: 150.0,
style: FlutterLogoStyle.horizontal,
duration: Duration(milliseconds: 100),
textColor: Theme.of(context).colorScheme.background, // 從上下文拿到背景
),
new Text( // 若是爲黑夜模式則按鈕文字爲白天模式,不然文字顯示爲黑夜模式
'點擊Logo更換${Config.dark ? "白天模式" : "黑夜模式"}',
style: new TextStyle(fontSize: 25.0),
),
],
),
),
),
new MaterialButton( // 跳轉按鈕
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => new NewPage('Flutter高級進階頁面二')));
},
child: new Text('跳轉到新頁面'),
),
],
);
}
@override
Widget build(BuildContext context) {
return new Theme( // 主題組件,可設置局部的主題樣式
data: Config.themeData, // 設置爲配置的主題數據
child: new Scaffold(
appBar: new AppBar(elevation: 0),
body: body(context), // 身體頁面body
),
);
}
}
再把NewPage測試頁面寫上:
class NewPage extends StatefulWidget {
final String title; // 接收的標題
NewPage(this.title);
@override
_NewPageState createState() => new _NewPageState(); // 建立有狀態頁面
}
class _NewPageState extends State<NewPage> {
@override
Widget build(BuildContext context) {
return new Theme(
child: new Scaffold( // title就是咱們的標題
appBar: new AppBar(title: new Text('頁面:${widget.title}'), elevation: 0),
body: new Center(
child: new Text(
'這是${widget.title}',
style: TextStyle(fontSize: 30.0),
),
),
),
data: Config.themeData, // 設置爲配置的主題數據
);
}
}
直接複製到本身的項目內便可運行。
本文分享自微信公衆號 - flutter開發精選(Study_Knowledge)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。