ABOUT ME

-

  • [ Flutter ] 다크모드 설정 구현하기
    Application/Flutter 2024. 7. 7. 20:34
    반응형

    스위치를 만들어 다크 모드 설정 구현


    Color Setting

    다크모드일때와 라이트모드일때 적용할 컬러를 세팅해준다.

    색상은 테마에 따라서 색상을 바꾸기위해서 final 변수가 아닌 일반 변수로 설정해준다.

    /* GLOBAL COLOR */
    Color bgColor = bgLightColor;
    Color boxColor = boxLightColor;
    Color textColor = darkGrey;
    Color iconColor = darkGrey;
    /* LIGHT THEME COLOR */
    final Color bgLightColor = hexToColor('f2f4f6');
    final Color boxLightColor = hexToColor('ffffff');
    /* DARK THEME COLOR */
    final Color bgDarkColor = hexToColor('141414');
    final Color boxDarkColor = hexToColor('282828');
    
    final Color white = hexToColor('ffffff');
    
    final Color red = hexToColor('FF6969');
    final Color redLight = hexToColor('FFB4B4');
    
    final Color blue = hexToColor('3FA2F6');
    final Color blueLight = hexToColor('9FD0FA');
    
    final Color darkGrey = hexToColor('333333');
    final Color dartLight = hexToColor('999999');
    
    final Color mint = hexToColor('6CE1A8');

    Provider 설치

    다크모드 사용 여부를 전역변수로 따로 빼서 적용시킬것이기에 provider를 이용

    dependencies:
      flutter:
        sdk: flutter
      #provider
      provider: ^6.0.0

     

    추후 DB저장 방식이 아닌 캐시 저장 방식으로 어플을 만들려고하여

    캐시에 저장할 변수들은 글로벌 변수로 따로 빼서 관리

    import 'package:flutter/material.dart';
    
    bool isGlobalDarkTheme = false;

     

    provider class 구축

    글로벌 변수에서 값을 가져와 초기값 세팅

    이후 값의 변경에 따라서 글로벌 변수값도 함께 변경

    이후 updateColor메소드를 활용하여 이전에 설정한 color들의 색상을 다 바꿔준다.

    import 'package:flutter/material.dart';
    import 'package:sumgo/config/colors.dart';
    import 'package:sumgo/data/global_cashe.dart';
    
    class ThemeProvider extends ChangeNotifier {
      late bool _isDarkMode = isGlobalDarkTheme; // 초기값 설정
    
      bool get isDarkMode => _isDarkMode;
    
      set isDarkMode(bool value) {
        _isDarkMode = !_isDarkMode;
        isGlobalDarkTheme = _isDarkMode;
        _updateColors();
        notifyListeners(); // 변경을 구독자에게 알림
      }
    
      void _updateColors() {
        if (_isDarkMode) {
          bgColor = bgDarkColor;
          boxColor = boxDarkColor;
          textColor = white;
          iconColor = white;
        } else {
          bgColor = bgLightColor;
          boxColor = boxLightColor;
          textColor = darkGrey;
          iconColor = darkGrey;
        }
      }
    }

    Switch Setting

    themeProvider

    final themeProvider = Provider.of<ThemeProvider>(context,listen: false);

    설정한 themeProvider를 불러와 적용

    switch의 값은 provider에서 값을 가져와 true false값으로 설정

    switch값이 바뀔때마다 provider의 set함수가 실행

    class _ViewModeChangeComponentState extends State<ViewModeChangeComponent> {
      @override
      Widget build(BuildContext context) {
        final themeProvider = Provider.of<ThemeProvider>(context,listen: false);
    
        return CustomContainer(
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text('다크모드 설정하기', style: TextStyle(color: textColor),),
                  CupertinoSwitch(
                      value: themeProvider.isDarkMode,
                      activeColor: mint,
                      onChanged: (bool? value) {
                      setState(() {
                        themeProvider.isDarkMode = value ?? false;
                  });
              },
            ),
                ]
            ),
          ),
        );
      }
    }

    Consumer

    main.dart에서 provider에서의 변경값을 전달받는다.

    Consumer는 provider로 전달받아서 값이 바뀌면 다시 렌더링을 시켜준다.

    @override
    Widget build(BuildContext context) {
      return ChangeNotifierProvider(
        create: (context) => ThemeProvider() ,
        child: Consumer<ThemeProvider>(
          builder: (context, themeProvider, child) {
            return MaterialApp(
              debugShowCheckedModeBanner: false,
              home: SafeArea(
                child: Scaffold(
                    backgroundColor: bgColor,
                    body: mainPages[selectBtn],
                    bottomNavigationBar: BottomNavigation(
                      selectedBtn: selectBtn,
                      onItemTapped: _onItemTapped,
                    )
                ),
              ),
            );
          }
        ),
      );

    결과적으로 모든 색상부분을 컬러를 넣고, consumer widget을 설정해주어 다시 재랜더링을 시켜준다.

    그럼 스위치를 누를때마다 해당 색상이 바뀌면서 다크모드 라이트모드 왔다갔다 할 수 있다.

    728x90
    반응형