はじめに
iPhoneではiOS 13からAndroidはAndroid 10からダークモードに対応しました。
ダークモードとは「黒地に白文字」を基調とした画面の配色です。 「目にやさしい」や「見やすい」等の特長があり、消費電力が抑えられるとも言われています。
自分も基本的には常にダークモードにしています。
今回はFlutterでダークモードの対応はどうやるのかを説明します。
環境
- Flutter 2.0.2
対応方法
対応方法はものすごく簡単です。
たった1行コードを書くだけです。
下記はプロジェクトを作成したときの初期のコードの状態のままです。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
そして、下記がダークモードに対応したときのコードです。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
darkTheme: ThemeData.dark(),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
わかりましたか?MaterialAppにdarkThemeというパラメーターを追加するだけです!
簡単でしょ?
結果
対応した端末で確認します。端末の設定からダークモードに切り替えます。
通常モード
ダークモード
ダークモードがかっこいいですね。
この対応だけだと問題が。。。
簡単に対応したいのであればこの対応で良いのですが、このままだとダークテーマ時にフォント等を設定できません。ですので下記のやり方をおすすめします。
サンプルコード
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: 'NotoSansCJKJp',
),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.red,
fontFamily: 'NotoSansCJKJp',
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
(NotoSansCJKJpのフォントをサンプルで追加しています。)
darkThemeに通常時と同じThemeDataを指定するのですが、ThemeDataのbrightnessにBrightness.darkを指定することで、基本配色がダークテーマになります。
あとはお好みで設定の設定でfontFamiry等を追加で変更します。
darkTheme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.red,
fontFamily: 'NotoSansCJKJp',
),
結果
ダークモード時にフォントもprimaryColorの色もちゃんと変わっています。
さいごに
もはやダークテーマだけで良いんじゃないかと思う今日このごろ。
コメント