この記事はFlutter 全部俺 Advent Calendar 12日目の記事です。
このアドベントカレンダーについて
このアドベントカレンダーは @itome が全て書いています。
基本的にFlutterの公式ドキュメントとソースコードを参照しながら書いていきます。誤植や編集依頼はTwitterにお願いします。
FlutterのThemeとはなにか
Flutterは、アプリに統一的なデザインスタイルを提供するために、Themeクラスを提供しています。
Themeを適切に使えば、最小限のコストでアプリのデザインを変更したり、ダークモードに対応したりできます。
Theme の基本的な使い方
Themeは基本的にMaterialAppとのセットで使います。MaterialAppのtheme: に指定したThemeDataが
アプリ全体に適用されます。
...
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
...
),
home: Scaffold(
...
テーマを各Widgetに適用させたい時は、Theme.of(context)で取得したThemeDataからスタイルを取り出して使います。
(Theme.of(context)で共通のThemeDataが取得できる仕組みに関しては
6日目の記事参照)
...
Text(
'Hello',
style: Theme.of(context).textTheme.body1,
),
...
基本的にはこれだけです。
Themeを切り替える
Themeの切り替えは通常の状態変更と同様にMaterialAppに渡すThemeDataを切り替えるだけでできます。
MaterialAppは内部でAnimatedThemeを使っているので、Themeの切り替え時に自動的にアニメーションも入れてくれます。
TextやAppBarなどの多くのWidgetは色のデフォルト値をTheme.of(context)から取得して指定しているので、
Themeを切り替えるだけでそれに合わせてWidgetの色が変わります
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
bool dark = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: dark ? ThemeData.dark() : ThemeData.light(),
home: Scaffold(
appBar: AppBar(title: Text('Toggle theme sample')),
body: Center(
child: RaisedButton(
onPressed: () {
setState(() => dark = !dark);
},
child: Text('Toggle theme'),
),
),
),
);
}
}
OSのダークモードに対応する
Andorid/iOSともに最新のOSではダークモードに対応していますが、
FlutterではThemeを使って簡単にダークテーマに対応することができます。
MaterialAppにtheme: に加えてdarkTheme: を追加するだけです。
...
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: Scaffold(
...
Theme で設定できるプロパティ一覧
かなりたくさんあるので、全て手づから設定するのは現実的ではないです。
基本的にデフォルトのTheme.light()もしくはTheme.dark()をつかい、
デザインに合わせて必要なところだけ変更する運用にするのが最適だと思います。
| プロパティ | 説明 |
|---|---|
brightness |
アプリの全体の明るさ。Brightness.lightと Brightness.darkがあります。 |
primaryColor |
アプリの基本色になります。AppBarやTabBar、FloatingActionButtonなど、アプリのメインとなるWidgetの背景色がこれになります |
primaryColorBrightness |
primaryColorにのみ適用されるbrightnessです。下のprimaryColorLightとprimaryColorDarkのどちらを使うかが決まります。 |
primaryColorLight |
Brightness.lightが指定されているときの primaryColor |
primaryColorDark |
Brightness.darkが指定されているときの primaryColor |
canvasColor |
MaterialType(Material Designの構成要素のこと、button``card``circleなどがある)のうち Material.canvasに適用される色です。 |
accentColor |
アプリのアクセントカラーです。ScrollViewをいっぱいまでスクロールしたときにでるoverscroll edge effectなどの色になります |
accentColorBrightness |
accentColorにのみ適用されるbrightnessです。下のprimaryColorLightとprimaryColorDarkのどちらを使うかが決まります。 |
scaffoldBackgroundColor |
ScaffoldWidgetの背景色です。 |
bottomAppBarColor |
BottomAppBarWidgetの背景色です。 |
cardColor |
MaterialWidgetにtype: MaterialType.cardを指定したときやCardWidgetの背景色です。 |
dividerColor |
DividerWidgetの色です。 |
focusColor |
Widgetがフォーカスされたときの色です。TextFieldの編集中の色などになります。 |
hoverColor |
Widgetがホバーされたときの色です。 |
splashColor |
InkWellのsplashの色です。![]() |
highlightColor |
InkWellのhighlightの色です。 |
splashFactory |
InkWellのsplashの効果をカスタマイズできるファクトリクラスを指定します。 |
selectedRowColor |
選択行の背景色です。デフォルトでは特に使われていません。 |
unselectedWidgetColor |
選択されていないWidgetの色です。CheckBox などの非選択時の色として、accentColorとの対で使われます。 |
disabledColor |
非有効化されたWidgetの色です。押せないCheckBoxの色などに使われます。 |
buttonTheme |
RaisedButtonなどのButton系Widgetのデフォルトの設定に使われます。サイズ、色、内部のTextWidgetのスタイルなど、さまざまな値が指定できます。 |
toggleButtonsTheme |
ToggleButtons版のButtonTheme。 |
buttonColor |
RaisedButtonなどのButton系Widgetの背景色です。 |
secondaryHeaderColor |
PaginatedDataTableのヘッダーの色です。 |
textSelectionColor |
TextFieldなど選択可能なTextWidgetの選択時の色です。 |
cursorColor |
TextFieldなどのカーソルの色です。 |
textSelectionHandleColor |
TextFieldなどで、文字を選択しているときのカーソルの色です。 |
backgroundColor |
背景色のうち、primaryColorが使われない部分の色です。ProgressIndicatorの残りの部分の色などに使われます。 |
dialogBackgroundColor |
Dialogの背景色です。 |
indicatorTheme |
TabBarの選択時のインジケーターの色です。 |
hintColor |
TextFieldのhintTextの色です。 |
errorColor |
エラーの色です。TextFieldのエラー文の色などに使われます。 |
toggleableActiveColor |
Switch``Radio``CheckBoxなどのトグルできるボタンの選択時の色です。 |
textTheme |
TextWidgetの基本的なスタイルです。body1``body2``title``caption``buttonなどのタイプに対するTextStyleを詰め合わせたものです。 |
primaryTextTheme |
primaryColorに対応するTextThemeです。 |
accentTextTheme |
accentColorに対応するTextThemeです。 |
inputDecorationTheme |
TextFieldなどに設定するInputDecorationのThemeです。hintや枠線などを指定できます。 |
iconTheme |
IconWidgetのThemeです。サイズと色を指定できます。 |
primaryIconTheme |
primaryColorに対応するIconThemeです。 |
accentIconTheme |
accentColorにタイソウルIconThemeです。 |
sliderTheme |
SliderWidgetのThemeです。サイズや形などを指定できます。 |
tabBarTheme |
TabBarWidgetのThemeです。インジケーターのスタイルやサイズなどを指定できます。 |
tooltipTheme |
TooltipWidgetのThemeです。サイズや形などを指定できます。 |
cardTheme |
CardWidgetのThemeです。色や形を指定できます。 |
clipTheme |
ClipCircleなどのClip系WidgetのThemeです。色や形などを指定できます。 |
platform |
ThemeごとにTargetPlatformを指定するためのプロパティです。実際のTargetPlatformとは異なる場合もあります。 |
materialTapTargetSize |
Material系のWidgetのタップ領域を指定できます。paddingとshrinkWrapから選べます。 |
applyElevationOverlayColor |
マテリアルデザインでelevation(浮いているような影が出る)エフェクトを表現する時に、overlayColorを利用するかどうかのフラグです。ダークテーマでは影の表現が難しいため、影の表現がオフになります。 |
pageTransitionsTheme |
画面遷移にどのようなアニメーションを使うかというThemeです。AndroidとiOSそれぞれ別に指定できます。 |
appBarTheme |
AppBarのThemeです。色やタイトルのスタイルを指定できます。 |
bottomAppBarTheme |
BottomAppBarのThemeです。色や形を指定できます。 |
colorScheme |
Widgetに制限されないカラーセットです。 |
snackBarTheme |
SnackBarWidgetのThemeです。色や形を指定できます。 |
dialogTheme |
DialogのThemeです。色やテキストのスタイルが指定できます。 |
floatingActionButtonTheme |
FloatingActionButtonWidgetのThemeです。色や形が指定できます。 |
typography |
どのロケールで、どのフォントを使うかを指定します。 |
cupertinoOverrideTheme |
Cupertino系のWidget(iOSライクなデザインのWidget)のTheme |
bottomSheetTheme |
BottomSheetWidgetのThemeです。形などを指定できます。 |
popupMenuTheme |
PopupMenuのThemeです。色やテキストのスタイルが指定できます。 |
bannerTheme |
MaterialBannerWidgetのThemeです。 |
dividerTheme |
DividerWidgetのThemeです。色やサイズなどを指定できます。 |
buttonBarTheme |
ButtonBarWidgetのThemeです。サイズなどを指定できます。 |
11日目: Flutterを既存のAndroid/iOSアプリに組み込む :
https://itome.team/blog/2019/12/flutter-advent-calendar-day11
13日目: FlutterのPlatformViewを理解する :
https://itome.team/blog/2019/12/flutter-advent-calendar-day13
