Flutter

[Flutter] Provider로 Bookmark 관리하기

dev.trams 2024. 5. 6. 22:41
반응형

Flutter 애플리케이션을 개발하다보면 데이터 관리가 중요한데요. 특히 상태 관리 라이브러리 중 하나인 Provider는 이를 간단하게 해결할 수 있는 좋은 도구입니다. 이번 튜토리얼에서는 Flutter Provider를 사용하여 북마크 데이터를 관리하는 예제를 만들어보겠습니다.

Provider란?

Flutter 앱에서 상태를 관리하고 필요한 데이터를 제공하는 방법 중 하나입니다. Provider는 InheritedWidget을 기반으로 구현되어 있어서 위젯 트리 전체에서 상태를 공유할 수 있습니다.

시작하기 전에

이 튜토리얼을 따라하기 위해 Flutter 개발 환경이 설치되어 있어야 합니다.

프로젝트 설정

새로운 Flutter 프로젝트를 생성하고, 필요한 패키지를 설치합니다.

flutter create bookmark_app
cd bookmark_app

pubspec.yaml 파일을 열고 provider 패키지를 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  provider: ^5.0.0

터미널에서 다음 명령을 실행하여 패키지를 설치합니다.

flutter pub get

Bookmark 모델 만들기

먼저, 북마크 데이터를 표현할 모델을 만들어야 합니다.

// models/bookmark.dart

class Bookmark {
  final String id;
  final String title;
  final bool checked;

  Bookmark({required this.id, required this.title, required this.checked});
}

Provider 구현하기

이제 Provider 클래스를 만들고, 북마크를 추가, 수정, 삭제하는 기능을 구현합니다.

// provider/bookmark_provider.dart

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

class BookmarkProvider with ChangeNotifier {
  List<Bookmark> _bookmarks = [];

  List<Bookmark> get bookmarks => _bookmarks;

  BookmarkProvider() {
    loadBookmarks();
  }

  Future<void> saveBookmarks() async {
    final prefs = await SharedPreferences.getInstance();
    final String encodeData = json.encode(_bookmarks
        .map((e) => {'id': e.id, 'title': e.title, 'checked': e.checked})
        .toList());
    await prefs.setString('bookmarks', encodeData);
  }

  Future<void> loadBookmarks() async {
    final prefs = await SharedPreferences.getInstance();
    final String? bookmarksString = prefs.getString('bookmarks');
    if (bookmarksString != null) {
      final List<dynamic> bookmarkJson = json.decode(bookmarksString);
      _bookmarks = bookmarkJson
          .map((e) => Bookmark(
                id: e['id'],
                title: e['title'],
                checked: e['checked'],
              ))
          .toList();
      notifyListeners();
    }
  }

  Future<void> addBookmark(Bookmark bookmark) async {
    _bookmarks.add(bookmark);
    await saveBookmarks();
    notifyListeners();
  }

  Future<void> toggleBookmark(String id) async {
    final bookmarkIndex =
        _bookmarks.indexWhere((element) => element.id == id);
    if (bookmarkIndex != -1) {
      _bookmarks[bookmarkIndex] = Bookmark(
        id: id,
        title: _bookmarks[bookmarkIndex].title,
        checked: !_bookmarks[bookmarkIndex].checked,
      );
      await saveBookmarks();
      notifyListeners();
    }
  }

  Future<void> removeBookmark(String id) async {
    _bookmarks.removeWhere((bookmark) => bookmark.id == id);
    await saveBookmarks();
    notifyListeners();
  }
}

화면 구현하기

이제 북마크를 표시하고 관리할 화면을 구현해봅시다.

// screens/bookmark_screen.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../provider/bookmark_provider.dart';
import '../models/bookmark.dart';

class BookmarkScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('북마크'),
      ),
      body: Consumer<BookmarkProvider>(
        builder: (context, provider, child) {
          final bookmarks = provider.bookmarks;
          if (bookmarks.isEmpty) {
            return Center(
              child: Text('북마크가 비어있습니다.'),
            );
          } else {
            return ListView.builder(
              itemCount: bookmarks.length,
              itemBuilder: (context, index) {
                final bookmark = bookmarks[index];
                return ListTile(
                  title: Text(bookmark.title),
                  leading: Checkbox(
                    value: bookmark.checked,
                    onChanged: (value) {
                      provider.toggleBookmark(bookmark.id);
                    },
                  ),
                  trailing: IconButton(
                    icon: Icon(Icons.delete),
                    onPressed: () {
                      provider.removeBookmark(bookmark.id);
                    },
                  ),
                );
              },
            );
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          final newBookmark = Bookmark(
            id: DateTime.now().toString(),
            title: '새로운 북마크',
            checked: false,
          );
          Provider.of<BookmarkProvider>(context, listen: false)
              .addBookmark(newBookmark);
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

앱 실행

마지막으로 메인 앱 파일에서 Provider를 초기화하고 화면을 표시합니다.

// main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:bookmark_app/provider/bookmark_provider.dart';
import 'package:bookmark_app/screens/bookmark_screen.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => BookmarkProvider(),
      child: MaterialApp(
        title: '북마크 앱',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: BookmarkScreen(),
      ),
    );
  }
}

마무리

이제 Flutter Provider를 사용하여 북마크를 관리하는 간단한 앱을 만들었습니다. Provider를 사용하면 데이터의 상태를 쉽게 관리할 수 있고, 필요한 곳에서 데이터를 사용할 수 있습니다. 계속해서 Flutter를 공부하면서 Provider의 다양한 기능을 익혀보세요!

반응형