본문으로 이동

플러터:데이터 저장(간단한 데이터): 두 판 사이의 차이

학교의 모든 지식. SMwiki
새 문서: {{플러터}} == 개요 == Flutter에서 화면을 이동하거나 앱을 재시작해도 데이터를 유지하려면 상태 관리와 로컬 저장 방법을 이해해야 합니다. 이 문서에서는 데시벨 슬라이더 예제를 통해 상태 유지 방법을 단계별로 학습합니다. --- == 1. 화면 내 상태 유지 (StatefulWidget) == === 예제 코드 === <syntaxhighlight lang="dart"> class DecibelPage extends StatefulWidget { @override _DecibelPageStat...
 
 
(같은 사용자의 중간 판 6개는 보이지 않습니다)
2번째 줄: 2번째 줄:


== 개요 ==
== 개요 ==
Flutter에서 화면을 이동하거나 앱을 재시작해도 데이터를 유지하려면 상태 관리와 로컬 저장 방법을 이해해야 합니다.
Flutter에서 화면을 이동하거나 앱을 재시작해도 데이터를 유지하려면 상태 관리와 로컬 저장 방법을 이해해야 한다.
이 문서에서는 데시벨 슬라이더 예제를 통해 상태 유지 방법을 단계별로 학습합니다.


---
이 문서에선 Hive를 이용한 로컬 DB 기반 데이터 저장에 대해 다룬다.


== 1. 화면 내 상태 유지 (StatefulWidget) ==
SharedPreferences 등 '키:값' 방식의 간단한 저장방식도 있지만, 규모가 조금만 커져도 DB 저장방식에 밀린다.


=== 예제 코드 ===
=== Hive의 특징 ===
<syntaxhighlight lang="dart">
* 매우 빠름 (binary 기반)
class DecibelPage extends StatefulWidget {
* 리스트, Map, 객체까지 저장 가능(클래스 형태도 저장)
  @override
* 오프라인 DB 역할 수행
  _DecibelPageState createState() => _DecibelPageState();
* iOS/Android 모두 지원
}
* 수백~수천 개 데이터 저장해도 빠름


class _DecibelPageState extends State<DecibelPage> {
=== Hive 저장 위치 ===
  double currentValue = 0;
{| class="wikitable"
|+
!운영체제
!설명
!비고
|-
|안드로이드
|/data/data/'''<패키지명>'''/files/hive/
|
* 앱만 접근 가능
* 파일 앱에서 보이지 않음
* 앱 삭제 시 데이터도 삭제됨
* 앱 종료/재부팅해도 유지됨
|-
|iOS
|Application/<UUID>/Documents/hive/
(앱 UUID는 설치할 때마다 달라짐)
|
* 앱 내부 전용 저장 공간
* 앱 종료 후에도 유지
* 앱 삭제 시 같이 삭제
|-
|Windows
|%APPDATA%\<앱폴더>\hive
|예시: C:\Users\<사용자>\AppData\Roaming\com.example.myapp\hive\
|-
|브라우저
|파일이 아닌, IndexedDB 내부에 저장됨.
(Chrome 기준: 개발자도구 → Application → IndexedDB)
F5 눌러도 저장된 값이 그대로 유지된다.
|(dart에서 작성한 <code>box</code>, <code>decibelBox</code> 등이 그대로 DB 이름이 됨)
|}


  @override
== Hive로 데이터 유지하기 ==
  Widget build(BuildContext context) {
=== 준비 ===
    return Scaffold(
pubspec.yaml 설정<syntaxhighlight lang="yaml">dependencies:
      body: Slider(
  hive: ^2.2.3
        min: 0,
  hive_flutter: ^1.1.0</syntaxhighlight>파일 변경 이후 flutter pub get
        max: 120,
        value: currentValue,
        onChanged: (value) {
          setState(() {
            currentValue = value;
          });
        },
      ),
    );
  }
}
</syntaxhighlight>


=== 특징 ===
=== 전체 코드 ===
* 화면 내에서만 값 유지
가장 기본 예제인 카운팅 앱을 변형한 것.
* 다른 화면으로 이동하면 값 초기화


---
참고: 브라우저로 실행하면 켤 때마다 다른 port로 실행되는데, 이는 전혀 다른 웹페이지를 연 것으로 인식되어 저장된 데이터를 사용하지 못한다. 다만, f5로 초기화 하면 기존 코드에선 카운팅이 0부터 시작되었던 반면, Hive를 쓴 경우 저장되어 있던 숫자 그대로 활용할 수 있다.<syntaxhighlight lang="dart">import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';


== 2. 화면 간 상태 공유 (Provider) ==
void main() async {
 
   WidgetsFlutterBinding.ensureInitialized();
=== 준비 ===
   await Hive.initFlutter();
<syntaxhighlight lang="yaml">
   await Hive.openBox('box'); // 'box'라는 이름으로 열기. Hive의 Box는 작은 데이터베이스 하나라고 생각하면 됨.
dependencies:
  runApp(MyApp());
   provider: ^6.0.0
</syntaxhighlight>
 
=== 예제 코드 ===
<syntaxhighlight lang="dart">
class DecibelModel extends ChangeNotifier {
   double value = 0;
 
   void setValue(double v) {
    value = v;
    notifyListeners();
  }
}
}


void main() {
class MyApp extends StatefulWidget {
   runApp(
   @override
    ChangeNotifierProvider(
  State<MyApp> createState() => _MyAppState();
      create: (_) => DecibelModel(),
      child: MyApp(),
    ),
  );
}
}


// 슬라이더 연결
class _MyAppState extends State<MyApp> {
Slider(
   final box = Hive.box('box');
  min: 0,
  int count = 0;
  max: 120,
  value: context.watch<DecibelModel>().value,
   onChanged: (v) => context.read<DecibelModel>().setValue(v),
)
</syntaxhighlight>


=== 특징 ===
  @override
* 앱이 켜져 있는 동안 유지
  void initState() {  // 앱 시작 시 초기화
* 여러 화면에서 값 공유 가능
    super.initState();
    count = box.get('count', defaultValue: 0); // 저장된 불러오기
  }


---
  void increase() {
    setState(() {
      count++;
      box.put('count', count); // 저장
    });
  }


== 3. 앱 재시작 후에도 데이터 유지 (SharedPreferences) ==
  @override
 
  Widget build(BuildContext context) {
=== 준비 ===
    return MaterialApp(
<syntaxhighlight lang="yaml">
      home: Scaffold(
dependencies:
        appBar: AppBar(title: Text("Hive 초간단 예제")),
  shared_preferences: ^2.1.1
        body: Center(child: Text("$count", style: TextStyle(fontSize: 40))),
        floatingActionButton: FloatingActionButton(
          onPressed: increase,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}
</syntaxhighlight>
</syntaxhighlight>
=== 저장하기 ===
<syntaxhighlight lang="dart">
final prefs = await SharedPreferences.getInstance();
await prefs.setDouble('decibel', 85);
</syntaxhighlight>
* `'decibel'` key에 85 저장
* “기본값 85” 의미가 아니라, 지금 저장하는 값
=== 불러오기 ===
<syntaxhighlight lang="dart">
double decibel = prefs.getDouble('decibel') ?? 0;
</syntaxhighlight>
* 저장된 값이 없으면 null 반환
* null일 경우 안전하게 0으로 사용 (`?? 0`)
=== 특징 ===
* 앱 재시작 후에도 값 유지
* 간단한 숫자, 문자열, bool 저장 가능
---
== 4. 실습 순서 추천 ==
# StatefulWidget으로 슬라이더 만들기 
# Provider로 화면 전환 후 값 유지 확인 
# SharedPreferences로 앱 재시작 후 값 유지 확인 
---
== 5. 핵심 포인트 ==
* `setDouble` → 저장하는 값 
* `getDouble ?? 기본값` → 값이 없을 때 사용할 안전한 기본값 
* 상태 관리 없이 단순 화면 전환만 하면 값 초기화 
* Provider, Riverpod 등 상태 관리 라이브러리를 사용하면 화면 간 공유 가능 
* SharedPreferences, Hive 등 로컬 저장을 활용하면 앱 종료 후에도 값 유지 가능

2026년 1월 7일 (수) 02:58 기준 최신판

틀:플러터 Dart:개요 플러터에 대한 지식 분류

  1. 플러터:개요
    1. 플러터:VSCode
    2. 플러터:안드로이드 스튜디오
  2. 플러터:실행
  3. 플러터:개념 잡기
    1. 플러터:화면 하나 만들기
    2. 플러터:변하는 화면(StatefulWidget)
    3. 플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)
    4. 플러터:화면 전환(Drawer)
    5. 플러터:입력 관련
      1. 플러터:버튼
      2. 플러터:키보드 입력
      3. 플러터:슬라이더
    6. 플러터:그래프 그리기(fl chart)
    7. 플러터:데이터 저장(간단한 데이터)
    8. 플러터:인증(Firebase 인증)(미완)
    9. 플러터:인증(OAuth2)(미완)
  4. 권한 사용
    1. 플러터:마이크 입력
  5. 위젯
    1. 플러터:아이콘
    2. 플러터:레이아웃 계열 위젯
    3. 플러터:네비게이션 계열 위젯
    4. 플러터:버튼
    5. 플러터:상태관리(미완)
  6. 플러터:DB연결
    1. 플러터:Firebase(미완)
    2. 플러터:MySQL(미완)
  7. 디자인
    1. 플러터:테마
    2. 플러터:앱바
  8. 플러터:배포
  9. 플러터:참고자료
  10. 플러터:위젯
    1. 플러터:공간배치용 위젯
  11. 플러터:라이브러리
    1. 플러터:logger

Flutter에서 화면을 이동하거나 앱을 재시작해도 데이터를 유지하려면 상태 관리와 로컬 저장 방법을 이해해야 한다.

이 문서에선 Hive를 이용한 로컬 DB 기반 데이터 저장에 대해 다룬다.

SharedPreferences 등 '키:값' 방식의 간단한 저장방식도 있지만, 규모가 조금만 커져도 DB 저장방식에 밀린다.

Hive의 특징

[편집 | 원본 편집]
  • 매우 빠름 (binary 기반)
  • 리스트, Map, 객체까지 저장 가능(클래스 형태도 저장)
  • 오프라인 DB 역할 수행
  • iOS/Android 모두 지원
  • 수백~수천 개 데이터 저장해도 빠름

Hive 저장 위치

[편집 | 원본 편집]
운영체제 설명 비고
안드로이드 /data/data/<패키지명>/files/hive/
  • 앱만 접근 가능
  • 파일 앱에서 보이지 않음
  • 앱 삭제 시 데이터도 삭제됨
  • 앱 종료/재부팅해도 유지됨
iOS Application/<UUID>/Documents/hive/

(앱 UUID는 설치할 때마다 달라짐)

  • 앱 내부 전용 저장 공간
  • 앱 종료 후에도 유지
  • 앱 삭제 시 같이 삭제
Windows %APPDATA%\<앱폴더>\hive 예시: C:\Users\<사용자>\AppData\Roaming\com.example.myapp\hive\
브라우저 파일이 아닌, IndexedDB 내부에 저장됨.

(Chrome 기준: 개발자도구 → Application → IndexedDB) F5 눌러도 저장된 값이 그대로 유지된다.

(dart에서 작성한 box, decibelBox 등이 그대로 DB 이름이 됨)

Hive로 데이터 유지하기

[편집 | 원본 편집]

pubspec.yaml 설정

dependencies:
  hive: ^2.2.3
  hive_flutter: ^1.1.0

파일 변경 이후 flutter pub get

전체 코드

[편집 | 원본 편집]

가장 기본 예제인 카운팅 앱을 변형한 것.

참고: 브라우저로 실행하면 켤 때마다 다른 port로 실행되는데, 이는 전혀 다른 웹페이지를 연 것으로 인식되어 저장된 데이터를 사용하지 못한다. 다만, f5로 초기화 하면 기존 코드에선 카운팅이 0부터 시작되었던 반면, Hive를 쓴 경우 저장되어 있던 숫자 그대로 활용할 수 있다.

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  await Hive.openBox('box');  // 'box'라는 이름으로 열기. Hive의 Box는 작은 데이터베이스 하나라고 생각하면 됨.
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final box = Hive.box('box');
  int count = 0;

  @override
  void initState() {  // 앱 시작 시 초기화
    super.initState();
    count = box.get('count', defaultValue: 0); // 저장된 값 불러오기
  }

  void increase() {
    setState(() {
      count++;
      box.put('count', count); // 저장
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Hive 초간단 예제")),
        body: Center(child: Text("$count", style: TextStyle(fontSize: 40))),
        floatingActionButton: FloatingActionButton(
          onPressed: increase,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}