Flutter 앱에서 가볍고 간단한 데이터를 영구적으로 저장
앱의 개인 메모장
키-값으로 데이터 저장
사용자 경험 크게 향상
비동기(Asynchronous) 프로그래밍
Null Safety와 기본값 설정
사용하는 법
shared_preferences: ^2.5.3
import 'package:shared_preferences/shared_preferences.dart';
예제)
버튼을 누르면 카운터에 변수 반영
저장하면 현재 카운터값이 영구저장
영구저장값은 앱 실행시, 새로고침 클릭시 호출
삭제를 클릭하면 영구저장값 삭제
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SharedPreferences 예제',
debugShowCheckedModeBanner: false,
home: CountStorage(),
);
}
}
class CountStorage extends StatefulWidget {
const CountStorage({super.key});
@override
State<CountStorage> createState() => _CountStorageState();
}
class _CountStorageState extends State<CountStorage> {
int _counter = 0;
final String _counterKey = 'count_value';
@override
void initState() {
super.initState();
_loadData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('예제 학습'),
backgroundColor: Colors.orange[300],
foregroundColor: Colors.white,
actions: [
IconButton(
onPressed: _loadData,
icon: Icon(Icons.refresh),
tooltip: '데이터 새로고침',
),
IconButton(
onPressed: _deleteCounter,
icon: Icon(Icons.delete_forever),
tooltip: '모든 데이터 삭제',
),
],
),
body: _buildBody(),
bottomNavigationBar: Container(
padding: EdgeInsets.all(16),
color: Colors.green[400],
child: Text(
textAlign: TextAlign.center,
'팁: 앱을 종료한뒤 다시 실행해보세요\n 저장한 값이 그대로 남게 됩니다',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
}
Column _buildBody() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
color: Colors.blue[100],
child: Column(
children: [
const SizedBox(height: 16),
Text(
'카운터',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.orange[100],
shape: BoxShape.circle,
),
child: Center(
child: Text(
'${_counter}',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
setState(() {
if (_counter > 0) {
_counter -= 1;
}
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red[300],
),
child: Text(
'-1',
style: TextStyle(color: Colors.white),
),
),
ElevatedButton(
onPressed: () {
setState(() {
_counter += 1;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue[300],
),
child: Text(
'+1',
style: TextStyle(color: Colors.white),
),
),
],
),
const SizedBox(height: 16),
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
width: double.infinity,
child: ElevatedButton.icon(
onPressed: _saveCounter,
label: Text('저장하기'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
),
),
],
),
)
],
);
}
//SharedPreference는 비동기로 동작한다
Future<void> _saveCounter() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
//현재 카운터 값 저장 (await: 응답 올때까지 기다려)
bool success = await prefs.setInt(_counterKey, _counter);
if (success) {
print('카운터 값 저장 성공: $_counter');
_showMessage('카운터 값이 저장됐습니다');
} else {
_showMessage('카운터 값 저장중 오류발생');
}
} catch (e) {
_showMessage('카운터 값 저장중 오류발생');
}
}
//카운터값 날리기
Future<void> _deleteCounter() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool success = await prefs.remove(_counterKey); // 특정 키 데이터 삭제
if (success) {
setState(() {
_counter = 0; // UI 값도 바로 초기화
});
print('카운터 값 삭제 성공');
_showMessage('카운터 값이 삭제됐습니다');
} else {
_showMessage('카운터 값 삭제 중 오류 발생');
}
} catch (e) {
_showMessage('카운터 값 삭제 중 오류 발생');
}
}
Future<void> _loadData() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
final int savedCounter = prefs.getInt(_counterKey) ?? 0;
setState(() {
_counter = savedCounter;
});
} catch (e) {
_showMessage('카운터 값 저장중 오류발생');
}
}
//사용자에게 메시지 보여주기
void _showMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message),
duration: const Duration(seconds: 2),
));
}
} //end
'Flutter' 카테고리의 다른 글
통신을 위한 모델과 리포지터리 설계 (0) | 2025.08.19 |
---|---|
플러터에 MVVM 패턴을 적용해 관심사를 분리 (1) | 2025.08.18 |
구글 지도 api 써보기 (1) | 2025.08.13 |
플러터) 콜백메서드, 아이의 일을 부모가 알게 하자 (0) | 2025.07.28 |
플러터) 레시피 앱 만들기 2. 메인페이지 코드구현 (2) | 2025.07.25 |