Flutter에서 지속적인 다크 모드 구현
프로젝트의 소스 코드를 찾을 수 있습니다here.
먼저 이를 시연하기 위해 간단한 UI를 생성합니다. 시연 목적으로 핀테크 샘플 앱 프런트엔드로 이동했습니다.
import 'package:darkmode/home/homepage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: HomePage(),
);
}
}
둘째, 시각적 테마를 정의할 수 있는 ThemeData를 이용하여 밝은 테마와 어두운 테마를 정의할 수 있는 클래스를 생성한다. 또한 iconTheme, appBarTheme 및 textTheme와 같은 ThemeData 내의 다양한 속성을 전달합니다.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
ThemeData lightThemeData(BuildContext context) {
return ThemeData.light().copyWith(
visualDensity: VisualDensity.adaptivePlatformDensity,
scaffoldBackgroundColor: Colors.white,
appBarTheme: appBarTheme,
iconTheme:const IconThemeData(color: Colors.black),
textTheme: Theme.of(context).textTheme.apply(bodyColor: Colors.black));
}
ThemeData darkThemeData(BuildContext context) {
return ThemeData.dark().copyWith(
visualDensity: VisualDensity.adaptivePlatformDensity,
scaffoldBackgroundColor:const Color(0xFF1D1D35),
appBarTheme: appBarTheme,
iconTheme:const IconThemeData(color: Colors.white),
textTheme: Theme.of(context).textTheme.apply(bodyColor: Colors.white));
}
const appBarTheme = AppBarTheme(centerTitle: false, elevation: 0);
셋째, Provider package 및 shared preferences package을 추가합니다. 제공자 패키지를 사용하여 앱 전체 테마 전환을 활성화하고 공유 기본 설정 패키지를 사용하여 지속된 테마 세부 정보를 저장하므로 앱을 종료하고 열 때 다시 올라가면 테마가 지속됩니다.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ThemeProvider extends ChangeNotifier {
final String key = "theme";
late SharedPreferences _prefs;
late bool _darkTheme;
bool get darkTheme => _darkTheme;
ThemeProvider() {
_darkTheme = true;
_loadFromPrefs();
}
toggleTheme() {
_darkTheme = !_darkTheme;
_saveToPrefs();
notifyListeners();
}
_initPrefs() async {
// if(_prefs == null)
_prefs = await SharedPreferences.getInstance();
}
_loadFromPrefs() async {
await _initPrefs();
_darkTheme = _prefs.getBool(key) ?? true;
notifyListeners();
}
_saveToPrefs()async {
await _initPrefs();
_prefs.setBool(key, _darkTheme);
}
}
이 작업을 완료하면 main.dart의 Materialapp으로 돌아가서 ChangeNotifier.notifyListeners가 호출될 때마다 자손의 ChangeNotifier 위젯을 수신하고 종속 항목을 다시 빌드하는 ChangeNotifierProvider 위젯으로 MaterialApp 위젯을 래핑합니다. 우리는 또한 우리를 위해 provider.of를 호출하고 테마의 변경 사항을 수신하여 필요할 때마다 다시 빌드하는 Consumer 위젯으로 MaterialApp 위젯을 래핑합니다.
import 'package:darkmode/home/homepage.dart';
import 'package:darkmode/provider/theme_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => ThemeProvider(),
child: Consumer<ThemeProvider>(
builder: (context, ThemeProvider notifier, child) {
return MaterialApp(
title: 'Flutter Demo',
theme: notifier.darkTheme
? darkThemeData(context)
: lightThemeData(context),
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}));
}
}
이제 밝은 모드와 어두운 모드 사이를 전환할 수 있는 스위치 버튼을 만듭니다. 전환 버튼을 소비자 위젯으로 래핑하여 ThemeProvider의 변경 사항을 수신합니다.
import 'package:darkmode/provider/theme_provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ChangeThemeButtonWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<ThemeProvider>(
builder: (context, notifier, child) => Switch.adaptive(
value: notifier.darkTheme,
onChanged: (val) {
notifier.toggleTheme();
//bool value of switch which is true or false
},
activeTrackColor: Colors.green[100],
inactiveTrackColor: Colors.green[300],
),
);
}
}
소스 코드를 찾을 수 있는 어두운 모드와 밝은 모드 사이의 전환을 시연하는 쉬운 방법으로 핀테크 프런트엔드를 만들었습니다here.
결과는 다음과 같습니다.
읽어주셔서 감사합니다. Flutter 개발에 관한 더 많은 기사를 기대해 주세요.
Reference
이 문제에 관하여(Flutter에서 지속적인 다크 모드 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/raicodesokwe/implementing-persistent-dark-mode-in-flutter-4854텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)