[flutter] shared_preferences를 사용하여 사용자가 선택한 앱 테마를 앱 내에서 로드하는 방법은?

앱 테마를 사용자가 선택할 수 있도록 하고, 사용자가 선택한 테마를 저장하여 앱이 다시 시작될 때 해당 테마를 로드하는 것은 사용자 경험을 향상시키는 중요한 요소입니다. Flutter에서 이를 구현하기 위해 shared_preferences 패키지를 사용할 수 있습니다. 이 패키지를 사용하면 간단한 키-값 저장소를 이용하여 사용자의 설정을 유지할 수 있습니다.

shared_preferences 패키지 설치

먼저, shared_preferences 패키지를 pubspec.yaml 파일에 추가하고, 패키지를 설치합니다.

dependencies:
  shared_preferences: ^2.0.6

이후 터미널에서 아래 명령어를 실행하여 패키지를 설치합니다.

flutter pub get

사용자가 테마 선택하도록 구현

사용자가 앱 테마를 선택할 수 있는 설정 화면을 구현합니다. 예를 들어, 간단한 드롭다운 버튼을 사용하여 여러 테마 옵션 중 하나를 선택하게 할 수 있습니다.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class ThemeScreen extends StatefulWidget {
  @override
  _ThemeScreenState createState() => _ThemeScreenState();
}

class _ThemeScreenState extends State<ThemeScreen> {
  String _selectedTheme = 'light'; // 기본 테마는 'light'로 설정

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('테마 설정'),
      ),
      body: Center(
        child: DropdownButton<String>(
          value: _selectedTheme,
          onChanged: (String? newValue) {
            setState(() {
              _selectedTheme = newValue!;
              _saveThemeToPrefs(newValue); // 사용자 선택 테마를 저장
            });
          },
          items: <String>['light', 'dark', 'custom']
              .map<DropdownMenuItem<String>>((String value) {
            return DropdownMenuItem<String>(
              value: value,
              child: Text(value),
            );
          }).toList(),
        ),
      ),
    );
  }

  _saveThemeToPrefs(String theme) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('theme', theme); // 사용자 선택 테마를 shared preferences에 저장
  }
}

앱 시작 시 테마 불러오기

이제, 앱이 시작될 때 사용자가 선택한 테마를 불러와서 적용해야 합니다.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _getThemeFromPrefs(),
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.hasData) {
          String theme = snapshot.data!;
          return MaterialApp(
            theme: theme == 'dark' ? ThemeData.dark() : ThemeData.light(),
            home: MyHomePage(),
          );
        } else {
          return CircularProgressIndicator(); // shared preferences에서 테마를 아직 불러오지 못한 경우 로딩 표시
        }
      },
    );
  }

  Future<String> _getThemeFromPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString('theme') ?? "light"; // 사용자 선택 테마를 shared preferences에서 불러옴
  }
}

class MyHomePage extends StatelessWidget {
  // 앱의 메인 화면
  // ...
}

이제 앱은 사용자가 선택한 테마를 shared_preferences에서 불러와서 적용하므로, 사용자가 설정한 테마가 앱을 다시 시작해도 유지됩니다.

이 방법을 통해 사용자가 선택한 앱 테마를 shared_preferences를 사용하여 저장하고, 앱이 시작될 때 해당 테마를 로드하는 기능을 구현할 수 있습니다.