[Flutter] Flutter로 책 상세 정보 화면 만들기: BookDetailScreen 클래스

StudipU·2024년 3월 5일
0

이번에는 Flutter를 사용하여 책 상세 정보 화면을 만드는 코드를 자세하게 분석해보겠습니다.

BookDetailScreen 클래스 소개 ✨

BookDetailScreen 클래스는 여러 화면에서 listItem container를 클릭했을 때 전환되는 책 상세정보 화면입니다. 해당 화면에서는 책 표지를 비롯하여, 제목, 저자, 출판사, 책 소개 등의 정보를 나타내며, 해당 도서에 대한 감상평을 남길 수 있는 감상평 쓰기 버튼이 있습니다.

주요 기능 및 코드 분석 🎭

1. 클래스 및 필수 라이브러리 임포트

아래 코드에서는 Flutter의 기본 라이브러리 외에도 책 리뷰 작성을 위한 화면인 WriteReviewWrapper 클래스와 데이터베이스에서 정보를 가져오는 함수들이 정의된 라이브러리를 임포트하고 있습니다.

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:military_bookstore/authentication/WriteReviewWrapper.dart';
import 'package:military_bookstore/database/get_aladin_database.dart';
import 'package:military_bookstore/database/get_database_Info.dart';
import 'package:military_bookstore/widget/appbar_widget.dart';
import 'package:military_bookstore/widget/drewer_widget.dart';
import 'package:military_bookstore/widget/nav_widget.dart';

import 'write_review_screen.dart';

2. BookDetailScreen 클래스 정의

아래 코드는 책 상세 정보를 표시하는 BookDetailScreen 클래스를 정의하고 있습니다. 이 클래스는 StatelessWidget을 상속받아 구현되어 있으며, 책의 제목(bookTitle)을 매개변수로 받아와야 합니다.

class BookDetailScreen extends StatelessWidget {
  final String bookTitle;

  BookDetailScreen({super.key, required this.bookTitle});

  
  Widget build(BuildContext context) {
    // 화면 크기 및 비율 계산
    double deviceWidth = MediaQuery.of(context).size.width;
    double deviceHeight = MediaQuery.of(context).size.height;

    double widthRatio = deviceWidth / 375;
    double heightRatio = deviceHeight / 812;

    return Scaffold(
      appBar: appbar_widget(context),
      drawer: drewer_widget(context),
      body: Center(
        child: Container(
            height: widthRatio * 812,
            clipBehavior: Clip.antiAlias,
            // 배경색상 설정
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment(-0.00, -1.00),
                end: Alignment(0, 1),
                colors: [
                  Color(0xA545B0C5),
                  Color(0xFF4580C5),
                  Color(0xFF4580C5)
                ],
              ),
            ),
            child: Column(
              children: [
                nav_widget(context),
                // ... 생략 ...
              ],
            )),
      ),
    );
  }
}

3. 책 표지, 저자, 출판사, 책 소개 내용 불러오기

아래 코드는 책의 이미지와 감상평 쓰기 버튼, 제목, 저자, 출판사 등을 표시하기 위해 정보를 불러오는 함수들 입니다. 이 함수들을 통해 FutureBuilder로 정보를 가져오고 있습니다.

Future<Image> getBookImage(String bookTitle) async {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;
  QuerySnapshot querySnapshot = await _firestore
      .collection('bookInfos')
      .where('title', isEqualTo: bookTitle)
      .limit(1)
      .get();
  Map<String, dynamic>? data = querySnapshot.docs[0].data() as Map<String, dynamic>?;
  String imageUrl = data!['thumbnail'];
  return getImage(imageUrl);
}

Future<Image> getImage(String imageUrl) async {
  if (imageUrl.isEmpty) {
    throw Exception('$imageUrl');
  }

  try {
    http.Response response = await http.get(Uri.parse(imageUrl));
    if (response.statusCode == 200) {
      return Image.memory(response.bodyBytes);
    } else {
      throw Exception('Failed to load image - ${response.statusCode}');
    }
  } catch (e) {
    throw Exception('Failed to load image - $e');
  }
}

Future<String> getAladinDescription(String bookTitle) async {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;
  QuerySnapshot querySnapshot = await _firestore
      .collection('aladinBooks')
      .where('title', isEqualTo: bookTitle)
      .limit(1)
      .get();
  Map<String, dynamic>? data = querySnapshot.docs[0].data() as Map<String, dynamic>?;
  String bookContents = data!['description'];

  return bookContents;
}

Future<String> getAladinAuthors(String bookTitle) async {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;
  QuerySnapshot querySnapshot = await _firestore
      .collection('aladinBooks')
      .where('title', isEqualTo: bookTitle)
      .limit(1)
      .get();
  Map<String, dynamic>? data = querySnapshot.docs[0].data() as Map<String, dynamic>?;
  String authorsString = data!['author'];
  return authorsString;
}

Future<String> getAladinPublisher(String bookTitle) async {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;
  QuerySnapshot querySnapshot = await _firestore
      .collection('aladinBooks')
      .where('title', isEqualTo: bookTitle)
      .limit(1)
      .get();
  Map<String, dynamic>? data = querySnapshot.docs[0].data() as Map<String, dynamic>?;
  String publisher = data!['publisher'];
  return publisher;
}

4. 감상평 쓰기 버튼


감상평 쓰기 버튼은 GestureDetector를 사용하여 터치 이벤트를 처리하고 있습니다. 이 감상평 쓰기 버튼을 클릭하면 해당 책에 대한 감상평을 작성하는 페이지로 전환됩니다. 감상평 쓰기 페이지는 다음 글에서 자세히 다루도록 하겠습니다.

Container(
  width: widthRatio * 155,
  height: heightRatio * 30,
  alignment: Alignment.topRight,
  child: GestureDetector(
    child: Container(
      padding: EdgeInsets.symmetric(vertical: heightRatio * 5),
      width: widthRatio * 90,
      decoration: ShapeDecoration(
        color: Color(0xFF46B0C6),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
        shadows: [
          BoxShadow(
            color: Color(0x3F000000),
            blurRadius: 4,
            offset: Offset(0, 4),
            spreadRadius: 0,
          )
        ],
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SizedBox(width: widthRatio * 2),
          Text(
            "감상평 쓰기",
            style: TextStyle(
              fontSize: 12,
              fontFamily: 'GowunBatang',
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
          SizedBox(width: widthRatio * 2),
          Icon(
            Icons.edit,
            color: Colors.white,
            size: 13,
          ),
        ],
      ),
    ),
    onTap: () {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => WriteReviewWrapper(
            bookTitle: bookTitle,
          ),
        ),
      );
    },
  ),
),
profile
컴공 대학생이 군대에서 작성하는 앱 개발 블로그

0개의 댓글