반응형
하트 버튼을 클릭해서 좋아하는 웹툰을 저장하는 기능을 마지막으로 담을 것이다.
어떻게 하면 핸드폰 저장소에 데이터를 담을 수 있을까?
shared_preferences라는 패키지를 이용하면 된다.
$ flutter pub add shared_preferences
버튼을 누를 때마다 웹툰의 ID를 가져와보자
일단 새로운 class member를 만들어야 한다.
class _DetailScreenState extends State<DetailScreen> {
late Future<WebtoonDetailModel> webtoon;
late Future<List<WebtoonEpisodeModel>> episodes;
late SharedPreferences prefs;
Future initPrefs() async {
prefs = await SharedPreferences.getInstance();
}
@override
void initState() {
// TODO: implement initState
super.initState();
webtoon = ApiService.getToonById(widget.id);
episodes = ApiService.getLatestEpisodesById(widget.id);
initPrefs();
}
이렇게 SharedPreferences.getInstance() 를 이용해서 클래스를 작성했고
이제 사용자 저장소 내부를 검색해서
likedToons라는 key 이름으로 String List가 있는지 확인할 것이다
하트 모양을 클릭함으로써 리스트에 넣고 안 넣고
핸드폰 저장소에 저장되게끔 이용해보았다 같은 기능을 한 번 다른 앱을 만들 때 활용해면보면 좋을 것 같다
클론코딩이지만 완성했다는 것에 뿌듯!
detail_screen.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:toonflix/models/webtoon_detail_model.dart';
import 'package:toonflix/models/webtoon_episode_model.dart';
import 'package:toonflix/services/api_service.dart';
import 'package:toonflix/widgets/episode_widget.dart';
class DetailScreen extends StatefulWidget {
final String title, thumb, id;
const DetailScreen({
super.key,
required this.title,
required this.thumb,
required this.id,
});
@override
State<DetailScreen> createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
late Future<WebtoonDetailModel> webtoon;
late Future<List<WebtoonEpisodeModel>> episodes;
late SharedPreferences prefs;
bool isLiked = false;
Future initPrefs() async {
prefs = await SharedPreferences.getInstance();
final likedToons = prefs.getStringList('likedToons');
if (likedToons != null) {
if (likedToons.contains(widget.id) == true) {
//화면이 변경될 때
setState(() {
isLiked = true;
});
}
} else {
await prefs.setStringList('likedToons', []);
}
}
@override
void initState() {
// TODO: implement initState
super.initState();
webtoon = ApiService.getToonById(widget.id);
episodes = ApiService.getLatestEpisodesById(widget.id);
initPrefs();
}
onHeartTap() async {
final likedToons = prefs.getStringList('likedToons');
if (likedToons != null) {
if (isLiked) {
likedToons.remove(widget.id);
} else {
likedToons.add(widget.id);
}
//핸드폰 저장소에 다시 List를 저장
await prefs.setStringList('likedToons', likedToons);
setState(() {
isLiked = !isLiked;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
elevation: 3,
backgroundColor: Colors.white,
foregroundColor: const Color.fromARGB(255, 13, 10, 0),
actions: [
IconButton(
onPressed: onHeartTap,
icon: Icon(
isLiked ? Icons.favorite : Icons.favorite_outline_outlined),
),
],
title: Text(widget.title,
style: const TextStyle(
color: Colors.black,
)),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(50),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Hero(
tag: widget.id,
child: Container(
width: 250,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
blurRadius: 15,
offset: const Offset(10, 10),
color: Colors.black.withOpacity(0.3),
)
],
),
child: Image.network(widget.thumb),
),
),
],
),
const SizedBox(
height: 25,
),
FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(snapshot.data!.about,
style: const TextStyle(
fontSize: 16,
)),
const SizedBox(
height: 15,
),
Text('${snapshot.data!.genre} / ${snapshot.data!.age}',
style: const TextStyle(
fontSize: 16,
)),
],
);
}
return const Text('.....');
},
future: webtoon,
),
const SizedBox(
height: 25,
),
FutureBuilder(
future: episodes,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
for (var episode in snapshot.data!)
Episode(episode: episode, webtoonId: widget.id),
],
);
}
return Container();
},
)
],
),
),
),
);
}
}
반응형
'Flutter > Flutter로 웹툰 앱 만들기' 카테고리의 다른 글
[노마드코더: Flutter 로 웹툰 앱 만들기] #6.16 Url Launcher (0) | 2022.12.20 |
---|---|
[노마드코더: Flutter 로 웹툰 앱 만들기] #6.15 Episodes (0) | 2022.12.20 |
[노마드코더: Flutter 로 웹툰 앱 만들기] #6.14 Detail Info (0) | 2022.12.20 |
[노마드코더: Flutter 로 웹툰 앱 만들기] #6.13 Futures (0) | 2022.12.14 |
[노마드코더: Flutter 로 웹툰 앱 만들기] #6.12 ApiService (0) | 2022.12.14 |