
flutter에서 firebase 사용시 조건에 관련된 것은 모두 where 함수를 사용한다.
where 함수의 매개변수를 통해서 어떠한 조건인지를 설정한다.
// 타입에 따라 영상 정보를 가져오는 함수
Future<List<Map<String, dynamic>>> getMovieDataByType(int movieType) async {
var querySnapShot = await FirebaseFirestore.instance.collection('movie_data').where('movie_type', isEqualTo: movieType ).get();
// 데이터를 담을 리스트
List<Map<String, dynamic>> results = [];
// 데이터를 리스트에 담아준다.
// 컬렉션에 담긴 모든 문서를 가져와 반복한다.
for(var doc in querySnapShot.docs){
// 문서에 담긴 데이터를 맵으로 추출하여 리스트에 담는다.
results.add(doc.data());
}
return results;
}
class _DramaScreenState extends State<DramaScreen> {
// 영화 데이터를 담을 변수
List<Map<String, dynamic>> movieData = [];
// 영화 포스터를 담을 상태 변수
List<Image> posterData = [];
// 영화 데이터를 가져오는 메서드
Future<void> getData() async {
// 영화 데이터를 가져온다.
var tempMovieData = await getMovieDataByType(1);
// 영화의 수 만큼 이미지 객체를 만들어준다.
posterData = List<Image>.generate(
tempMovieData.length,
(index) => Image.asset('lib/assets/images/loading.gif')
);
// 영화 데이터를 통해 상태를 설정한다.
setState(() {
movieData = tempMovieData;
});
// 포스터 데이터를 받아오며 상태를 설정한다.
for(int i=0; i<tempMovieData.length; i++){
// i번째 영화 포스터 객체를 가져온다.
var tempImage = await getImageData(tempMovieData[i]['movie_poster']);
setState(() {
posterData[i] = tempImage;
});
}
}
void initState() {
super.initState();
getData();
}
body: GridView.builder(
// 보여줄 항목의 개수
itemCount: movieData.length,
// 그리드 뷰의 항목 하나를 구성하는 함수
Widget makeGridItem(BuildContext context, List<Map<String, dynamic>> movieData, List<Image> posterData, int index){
return InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DetailScreen(),
fullscreenDialog: true,
)
);
},
child: posterData[index],
);
}
itemBuilder: (context, index) => makeGridItem(context, movieData, posterData, index),

// 찜한 영화 정보를 가져오는 함수
Future<List<int>> getLikeMovieList() async {
// 찜한 영화의 번호 정보를 가져온다.
var querySnapShot = await FirebaseFirestore.instance.collection('movie_like').doc('like_doc').get();
// 데이터를 담을 리스트
List<int> results = [];
var map = querySnapShot.data();
// 컬렉션과 문서가 있을 경우
if(map != null){
// likes 필드의 저장되어 있는 배열을 가져와 담아준다.
for(var idx in map['likes']){
results.add(idx);
}
}
return results;
}
class _HomeScreenState extends State<HomeScreen> {
// 영화 데이터를 담을 상태 변수
List<Map<String, dynamic>> movieData = [];
// 영화 포스터를 담을 상태 변수
List<Image> posterData = [];
// 지금 뜨는 콘텐츠 정보를 담을 리스트
List<int> hotMovie = [];
// 찜한 영화 번호를 담을 리스트
List<int> likeMovie = [];
Future<void> getData() async {
// 영화 데이터를 가져온다.
var tempMovieData = await getMovieData();
// print('home screen - $tempMovieData');
// getImageData(tempMovieData.first['movie_poster']);
// 영화의 수 만큼 이미지 객체를 만들어준다.
posterData = List<Image>.generate(
// 리스트가 담을 객체의 개수
tempMovieData.length,
// 리스트가 담을 객체를 생성해 반환해준다.
(index) => Image.asset('lib/assets/images/loading.gif'),
);
// 지금 뜨는 콘텐츠 정보를 받아온다.
hotMovie = await getHotMovieList();
// 찜한 영화 번호 정보를 받아온다.
likeMovie = await getLikeMovieList();
body: ListView(
children: [
// 상단 회전 목마
HomeCarouselSlider(movieData, posterData, likeMovie),
class HomeCarouselSlider extends StatefulWidget {
// 영화 데이터를 담을 상태 변수
List<Map<String, dynamic>> movieData;
// 영화 포스터를 담을 상태 변수
List<Image> posterData;
// 찜한 영화 번호를 담을 상태 변수
List<int> likeMovie;
HomeCarouselSlider(this.movieData, this.posterData, this.likeMovie, {super.key});
// 찜
Column(
children: [
// 현재 보여지는 영화의 번호가 찜한 영화 리스트에 있는지
widget.likeMovie.contains(widget.movieData[imagePosition]['movie_idx'])
? IconButton(onPressed: () {}, icon: Icon(Icons.check))
: IconButton(onPressed: () {}, icon: Icon(Icons.add)),
const Text("내가 찜한 콘텐츠", style: TextStyle(fontSize: 11)),
],
),
// 찜한 영화 정보를 새롭게 저장하는 함수
Future<void> setLikeMovie(List<int> likeMovie) async {
await FirebaseFirestore.instance.collection('movie_like').doc('like_doc').set({
'likes' : likeMovie,
});
}
Column(
children: [
// 현재 보여지는 영화의 번호가 찜한 영화 리스트에 있는지
widget.likeMovie.contains(widget.movieData[imagePosition]['movie_idx'])
? IconButton(
onPressed: () {
setState(() {
// 현재의 영화 번호를 likeMovie에서 제거한다.
widget.likeMovie.remove(widget.movieData[imagePosition]['movie_idx']);
// 저장한다.
setLikeMovie(widget.likeMovie);
});
},
icon: const Icon(Icons.check),
)
: IconButton(
onPressed: () {
setState(() {
// 현재의 영화 번호를 likeMovie에 저장한다.
widget.likeMovie.add(widget.movieData[imagePosition]['movie_idx']);
// 저장한다.
setLikeMovie(widget.likeMovie);
});
},
icon: const Icon(Icons.add)
),
const Text("내가 찜한 콘텐츠", style: TextStyle(fontSize: 11)),
],
),

// 전달되는 영화 번호에 해당하는 영화 데이터를 반환한다.
// 영화 데이터 전체를 가져오는 함수
Future<List<Map<String, dynamic>>> getMovieDataByMovieIndexes(List<int> movieIndexes) async {
// 데이터를 담을 리스트
List<Map<String, dynamic>> results = [];
if(movieIndexes.isNotEmpty){
// movie_data 컬렉션에 저장되어 있는 모든 문서를 가져온다.
var querySnapShot = await FirebaseFirestore.instance.collection('movie_data').where('movie_idx', whereIn: []).get();
// 데이터를 리스트에 담아준다.
// 컬렉션에 담긴 모든 문서를 가져와 반복한다.
for(var doc in querySnapShot.docs){
// 문서에 담긴 데이터를 맵으로 추출하여 리스트에 담는다.
results.add(doc.data());
}
}
return results;
}
class _LikeScreenState extends State<LikeScreen> {
// 영화 데이터를 담을 상태 변수
List<Map<String, dynamic>> movieData = [];
// 영화 포스터를 담을 상태 변수
List<Image> posterData = [];
// 찜한 영화 번호를 담을 상태 변수
List<int> likeMovie = [];
// 데이터를 가져오는 함수
Future<void> getData() async {
// 찜한 영화 번호 정보를 받아온다.
likeMovie = await getLikeMovieList();
// 영화 데이터를 가져온다.
var tempMovieData = await getMovieDataByMovieIndexes(likeMovie);
// 영화의 수 만큼 이미지 객체를 만들어준다.
posterData = List<Image>.generate(
// 리스트가 담을 객체의 개수
tempMovieData.length,
// 리스트가 담을 객체를 생성해 반환해준다.
(index) => Image.asset('lib/assets/images/loading.gif'),
);
// 영화 데이터를 통해 상태를 설정한다.
setState(() {
movieData = tempMovieData;
});
// 포스터 데이터를 받아오며 상태를 설정해준다.
for(int i=0; i<tempMovieData.length; i++){
// i번째 영화 포스터 객체를 가져온다.
var tempImage = await getImageData(tempMovieData[i]['movie_poster']);
// 받아온 이미지 객체를 포스터를 담을 리스트에 담아주고 상태를 설정한다.
setState(() {
posterData[i] = tempImage;
});
}
}
void initState() {
super.initState();
getData();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: LikeTopAppBar(),
body: Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: LikeListView(movieData, posterData, likeMovie),
),
);
}
class LikeListView extends StatefulWidget {
// 영화 데이터를 담을 상태 변수
List<Map<String, dynamic>> movieData;
// 영화 포스터를 담을 상태 변수
List<Image> posterData;
// 찜한 영화 번호를 담을 상태 변수
List<int> likeMovie;
LikeListView(this.movieData, this.posterData, this.likeMovie, {super.key});
State<LikeListView> createState() => _LikeListViewState();
}
class _LikeListViewState extends State<LikeListView> {
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.movieData.length,
itemBuilder: (context, index) => makeListItem(context),
);
}
}
class _LikeListViewState extends State<LikeListView> {
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.movieData.length,
itemBuilder: (context, index) => makeListItem(context, widget.movieData, widget.posterData, widget.likeMovie, index),
);
}
}
// 리스트 뷰의 항목 하나를 구성하는 함수
Widget makeListItem(int index){
Expanded(
child:Row(
children: [
Image(image: widget.posterData[index].image, width: 100),
const Padding(padding: EdgeInsets.only(right: 10)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.movieData[index]['movie_title'], overflow: TextOverflow.ellipsis),
Text('출연진 : ${widget.movieData[index]['movie_actor']}', overflow: TextOverflow.ellipsis),
Text('제작진 : ${widget.movieData[index]['movie_director']}', overflow: TextOverflow.ellipsis),
],
),
),
],
),
),
IconButton(
onPressed: () {
// index번째 항목을 제거한다.
setState(() {
widget.movieData.removeAt(index);
widget.posterData.removeAt(index);
widget.likeMovie.removeAt(index);
});
// 찜 데이터를 새롭게 저장한다.
setLikeMovie(widget.likeMovie);
},
icon: const Icon(Icons.delete)
),

class DetailScreen extends StatefulWidget {
// 영화 데이터
Map<String, dynamic> movieData = Map<String, dynamic>();
// 포스터
Image posterData= Image.asset('lib/assets/images/youtube_logo.gif');
DetailScreen.test(this.movieData, this.posterData{super.key});
DetailScreen({super.key});
State<DetailScreen> createState() => _DetailScreenState();
}
// 정보
Column(
children: [
IconButton(
onPressed: () {
// DetailScreen을 띄워준다.
Navigator.of(context).push(
MaterialPageRoute(
// 보여질 다음 화면을 설정한다.
builder: (context) => DetailScreen.test(widget.movieData[imagePosition], widget.posterData[imagePosition]),
// 다이얼로그로 보여지게 한다.
fullscreenDialog: true
)
);
},
icon: Icon(Icons.info)
),
Text("정보", style: TextStyle(fontSize: 11))
],
),
class _DetailScreenState extends State<DetailScreen> {
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
Stack(
children: [
Container(
// 배경 이미지를 깔아준다.
width: double.maxFinite,
decoration: BoxDecoration(
image: DecorationImage(
image: widget.posterData.image,
// 포스터 이미지
Container(
padding: EdgeInsets.fromLTRB(0, 45, 0, 10),
child: widget.posterData,
height: 300,
),
// 설명
Container(
padding: EdgeInsets.all(7),
child: Text(
widget.movieData['movie_info'],
textAlign: TextAlign.center,
style: TextStyle(fontSize: 13),
),
),
// 영화 제목
Container(
padding: EdgeInsets.all(7),
child: Text(
widget.movieData['movie_title'],
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16),
),
),
// 영화 설명
Container(
padding: EdgeInsets.all(5),
child: Text(widget.movieData['movie_detail_info']),
),
// 출연진
Container(
padding: EdgeInsets.all(5),
alignment: Alignment.centerLeft,
child: Text(
'출연 : ${widget.movieData['movie_actor']}',
style: TextStyle(
color: Colors.white60,
fontSize: 12
),
),
),
// 제작진
Container(
padding: EdgeInsets.all(5),
alignment: Alignment.centerLeft,
child: Text(
'제작진 : ${widget.movieData['movie_director']}',
style: TextStyle(
color: Colors.white60,
fontSize: 12
),
),
),
class DetailScreen extends StatefulWidget {
// 영화 데이터
Map<String, dynamic> movieData = Map<String, dynamic>();
// 포스터
Image posterData= Image.asset('lib/assets/images/youtube_logo.gif');
DetailScreen(this.movieData, this.posterData, {super.key});
State<DetailScreen> createState() => _DetailScreenState();
}
