この記事は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 |
Scaffold Widgetの背景色です。 |
bottomAppBarColor |
BottomAppBar Widgetの背景色です。 |
cardColor |
Material Widgetにtype: MaterialType.card を指定したときやCard Widgetの背景色です。 |
dividerColor |
Divider Widgetの色です。 |
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のデフォルトの設定に使われます。サイズ、色、内部のText Widgetのスタイルなど、さまざまな値が指定できます。 |
toggleButtonsTheme |
ToggleButtons 版のButtonTheme 。 |
buttonColor |
RaisedButton などのButton 系Widgetの背景色です。 |
secondaryHeaderColor |
PaginatedDataTable のヘッダーの色です。 |
textSelectionColor |
TextField など選択可能なText Widgetの選択時の色です。 |
cursorColor |
TextField などのカーソルの色です。 |
textSelectionHandleColor |
TextField などで、文字を選択しているときのカーソルの色です。 |
backgroundColor |
背景色のうち、primaryColor が使われない部分の色です。ProgressIndicator の残りの部分の色などに使われます。 |
dialogBackgroundColor |
Dialog の背景色です。 |
indicatorTheme |
TabBar の選択時のインジケーターの色です。 |
hintColor |
TextField のhintText の色です。 |
errorColor |
エラーの色です。TextField のエラー文の色などに使われます。 |
toggleableActiveColor |
Switch``Radio``CheckBox などのトグルできるボタンの選択時の色です。 |
textTheme |
Text Widgetの基本的なスタイルです。body1``body2``title``caption``button などのタイプに対するTextStyle を詰め合わせたものです。 |
primaryTextTheme |
primaryColor に対応するTextTheme です。 |
accentTextTheme |
accentColor に対応するTextTheme です。 |
inputDecorationTheme |
TextField などに設定するInputDecoration のTheme です。hintや枠線などを指定できます。 |
iconTheme |
Icon WidgetのTheme です。サイズと色を指定できます。 |
primaryIconTheme |
primaryColor に対応するIconTheme です。 |
accentIconTheme |
accentColor にタイソウルIconTheme です。 |
sliderTheme |
Slider WidgetのTheme です。サイズや形などを指定できます。 |
tabBarTheme |
TabBar WidgetのTheme です。インジケーターのスタイルやサイズなどを指定できます。 |
tooltipTheme |
Tooltip WidgetのTheme です。サイズや形などを指定できます。 |
cardTheme |
Card Widgetの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 |
SnackBar WidgetのTheme です。色や形を指定できます。 |
dialogTheme |
Dialog のTheme です。色やテキストのスタイルが指定できます。 |
floatingActionButtonTheme |
FloatingActionButton WidgetのTheme です。色や形が指定できます。 |
typography |
どのロケールで、どのフォントを使うかを指定します。 |
cupertinoOverrideTheme |
Cupertino 系のWidget(iOSライクなデザインのWidget)のTheme |
bottomSheetTheme |
BottomSheet WidgetのTheme です。形などを指定できます。 |
popupMenuTheme |
PopupMenu のTheme です。色やテキストのスタイルが指定できます。 |
bannerTheme |
MaterialBanner WidgetのTheme です。 |
dividerTheme |
Divider WidgetのTheme です。色やサイズなどを指定できます。 |
buttonBarTheme |
ButtonBar Widgetの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