다크 모드로 전환 시 전체 위젯을 refresh 해줘야 한다. 그러므로 MaterialApp, CupertinoApp을 ValueListenableBuilder 또는 ChangeNotifierProvider로 감싸줘야 한다. 그밖에 상태 관리 패키지마다 다른 방법이 있을 것이다.
void main() async {
await Hive.initFlutter();
await Hive.openBox('themeData');
runApp(DarkModeDemo());
}
class DarkModeDemo extends StatelessWidget {
const DarkModeDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<Box>(
valueListenable: Hive.box('themeData').listenable(keys: ['darkMode']),
builder: (context, box, child) {
var darkMode = box.get('darkMode', defaultValue: false);
return MaterialApp(
themeMode: darkMode ? ThemeMode.dark : ThemeMode.light,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text('Hive Dark Mode Demo'),
),
body: Center(
child: Column(
children: [
Switch(
value: darkMode,
onChanged: (value) {
box.put('darkMode', value);
},
),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Card Color'),
),
)
],
),
),
),
);
},
);
}
}
Android, iOS 각각 다른 테마를 적용할 때
2가지의 OS, 2가지의 테마(라이트 모드, 다크 모드)로 나누는 것이 유지보수 측면에서 더 좋을 것이다. 나중에 Web을 추가하게 된다면 추가도 간편하다. 그리고 현재 개발 중인 앱에서는 아래의 코드 블록처럼 적용을 하였는데... 아래처럼 분류하는 것이 더 좋은 것 같다고 생각한다.
- Android
- android_light_theme.dart
- android_dark_theme.dart
- iOS
- iOS_light_theme.dart
- iOS_dark_theme.dart
class ThemeColor {
static ThemeData materialThemeData(BuildContext context, bool darkMode) {
return ThemeData(
appBarTheme: AppBarTheme(
backgroundColor: darkMode ? Color(0xFF424242) : Colors.blue,
),
canvasColor: darkMode ? Color(0xFF303030) : Colors.white,
cardColor: darkMode ? Colors.white : Colors.green,
);
}
}
2022.01.10 - [Flutter/개발문서] - Flutter Hive 라이브러리
2022.01.11 - [Flutter/개발문서] - Flutter platform widgets 라이브러리 문서
Full Source Code (더보기 클릭)
더보기
main.dart
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
void main() async {
await Hive.initFlutter();
await Hive.openBox('themeData');
runApp(DarkModeDemo());
}
class DarkModeDemo extends StatelessWidget {
const DarkModeDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<Box>(
valueListenable: Hive.box('themeData').listenable(keys: ['darkMode']),
builder: (context, box, child) {
var darkMode = box.get('darkMode', defaultValue: false);
return MaterialApp(
themeMode: darkMode ? ThemeMode.dark : ThemeMode.light,
// theme: ThemeColor.materialThemeData(context, darkMode),
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text('Hive Dark Mode Demo'),
),
body: Center(
child: Column(
children: [
Switch(
value: darkMode,
onChanged: (value) {
box.put('darkMode', value);
},
),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Card Color'),
),
)
],
),
),
),
);
},
);
}
}
theme_color.dart
import 'package:flutter/material.dart';
class ThemeColor {
static ThemeData materialThemeData(BuildContext context, bool darkMode) {
return ThemeData(
appBarTheme: AppBarTheme(
backgroundColor: darkMode ? Color(0xFF424242) : Colors.blue,
),
canvasColor: darkMode ? Color(0xFF303030) : Colors.white,
cardColor: darkMode ? Colors.white : Colors.green,
);
}
}
'Flutter > Document' 카테고리의 다른 글
Flutter firebase 수동 추가 문서 (0) | 2022.05.08 |
---|---|
Flutter text over flow 적용안될때 (0) | 2022.05.05 |
Flutter 상태관리 (Ephemeral, App State) (0) | 2022.01.13 |
Flutter async await 정리 문서 (0) | 2021.08.16 |
compileSdkVersion , minSdkVersion , targetSdkVersion (0) | 2021.05.28 |