티스토리 뷰

반응형

Flutter로 To-Do 앱 만들기 (2): 데이터 저장 및 유지 (shared_preferences 활용)

이전 글에서는 Flutter에서 기본적인 To-Do 앱을 만들어 할 일을 추가하고 삭제할 수 있도록 했습니다.
하지만 현재 앱을 종료하면 데이터가 사라집니다.
이번 글에서는 앱을 껐다 켜도 할 일 목록이 유지되도록 로컬 저장소를 활용하는 방법을 배웁니다.


✅ 데이터 저장을 위한 shared_preferences 패키지

Flutter에서 간단한 로컬 데이터 저장을 할 때는 shared_preferences 패키지가 자주 사용됩니다.
이 패키지는 **기본적인 키-값 저장 방식(간단한 JSON)**을 제공하며, 작은 데이터(설정값, 간단한 리스트 등)를 저장하는 데 적합합니다.


✅ 1. shared_preferences 패키지 설치

📌 터미널에서 패키지 추가

flutter pub add shared_preferences

📌 pubspec.yaml 확인

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: latest_version

✅ 2. 기존 코드에 로컬 저장 기능 추가

반응형

이제 To-Do 목록을 앱을 종료해도 유지되도록 수정합니다.

📌 lib/main.dart 업데이트

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

void main() => runApp(const TodoApp());

class TodoApp extends StatelessWidget {
  const TodoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'To-Do App',
      home: const TodoHomePage(),
    );
  }
}

class TodoHomePage extends StatefulWidget {
  const TodoHomePage({super.key});

  @override
  State<TodoHomePage> createState() => _TodoHomePageState();
}

class _TodoHomePageState extends State<TodoHomePage> {
  final TextEditingController _controller = TextEditingController();
  List<Map<String, dynamic>> _todos = [];

  @override
  void initState() {
    super.initState();
    _loadTodos(); // 앱 시작 시 저장된 데이터 불러오기
  }

  Future<void> _loadTodos() async {
    final prefs = await SharedPreferences.getInstance();
    final String? todosString = prefs.getString('todos');
    if (todosString != null) {
      setState(() {
        _todos = List<Map<String, dynamic>>.from(jsonDecode(todosString));
      });
    }
  }

  Future<void> _saveTodos() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('todos', jsonEncode(_todos));
  }

  void _addTodo() {
    final text = _controller.text.trim();
    if (text.isEmpty) return;

    setState(() {
      _todos.add({'id': DateTime.now().millisecondsSinceEpoch, 'text': text});
      _controller.clear();
    });

    _saveTodos(); // 할 일 추가 후 저장
  }

  void _deleteTodo(int id) {
    setState(() {
      _todos.removeWhere((todo) => todo['id'] == id);
    });

    _saveTodos(); // 삭제 후 저장
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('할 일 목록')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(
                hintText: '할 일을 입력하세요',
              ),
              onSubmitted: (_) => _addTodo(),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: _addTodo,
              child: const Text('추가'),
            ),
            const SizedBox(height: 20),
            Expanded(
              child: ListView.builder(
                itemCount: _todos.length,
                itemBuilder: (context, index) {
                  final todo = _todos[index];
                  return Card(
                    child: ListTile(
                      title: Text(todo['text']),
                      trailing: IconButton(
                        icon: const Icon(Icons.delete),
                        onPressed: () => _deleteTodo(todo['id']),
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

✅ 3. 기능 추가 및 개선

추가된 기능 설명

initState() 앱 실행 시 저장된 데이터 불러오기
_loadTodos() SharedPreferences에서 JSON 데이터 로드
_saveTodos() To-Do 목록이 변경될 때 SharedPreferences에 저장
_addTodo(), _deleteTodo() 저장 기능 추가

✅ 실행 결과 예시

▶️ 앱을 종료 후 다시 실행하면 목록이 유지됨

  1. "Flutter 공부하기" 입력 후 추가
  2. 앱을 종료하고 다시 실행
  3. 이전 상태 그대로 유지됨
[ 할 일을 입력하세요 ] [추가 버튼]
---------------------------
- Flutter 공부하기  [🗑️]
- 운동하기          [🗑️]

✅ 4. shared_preferences 사용 시 주의할 점

  1. 대량의 데이터 저장에는 적합하지 않음
    → SQLite, Hive 같은 DB를 고려
  2. 데이터 암호화 필요 시 flutter_secure_storage 사용
  3. List 형태 데이터는 JSON으로 변환하여 저장해야 함

✅ 다음 글 예고

다음 편에서는 다크 모드 지원과 함께,
할 일 완료 상태를 체크할 수 있는 기능을 추가해 UI를 개선해보겠습니다! 😎


다음 글에서는 UI 개선 & 다크 모드 적용을 진행할까요? 😊

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함
반응형