[Flutter] RestaurantDetailScreen-③ProductCard 작업

겨레·2024년 7월 16일
0

URL에서 가져온 데이터를 화면에 보여주자!
그런데... 그러기 위해서는 메뉴 카드를 만들어야 한다. 그럼 메뉴 카드들을 만들어보자!


메뉴 카드들은 어느 폴더에 넣는 게 좋을까?
처음에 난 당연히 restaurant 폴더에 넣어야 될 거라고 생각했다.

하지만! 스웨거 API를 보면 맨 앞에 URL 값들로 인해 이미 나눠져 있음!
user와 관련된 건 user 태그로 나눠져 있고,
auth와 관련된 건 auth 태그로 나눠져 있음...

메뉴(상품)을 보면...
product 태그로 나눠져 있는 걸 알 수 있다.
그래서 폴더를 따로 만들거임!

① lib/product/component 폴더 생성
그 안에 product_card.dart 파일을 만들어준다.


② Container를 Row 위젯으로 수정
Container를 Row 위젯으로 수정
좌에서 우로 이미지, 글자들에 랜더링 되고 있으니까 Row 위젯으로 수정하고 코드 작성.
이미지는 샘플로 일단 넣어두자.

  • product_card.dart 코드
import 'package:flutter/material.dart';

class ProductCard extends StatelessWidget {
  const ProductCard({super.key});

  
  Widget build(BuildContext context) {
    return Row(
      children: [
        Image.asset('asset/img/food/ddeok_bok_gi.jpg'),
      ],
    );
  }
}

그리고 이 product card를 보여주기 위해서 restaurant_detail_screen.dart 코드에 ProductCard를 넣어준다.

ㅋㅋㅋ 그런데 지금 이미지가 엄청 크게 들어가서 오버플로우 발생!

오버플로우를 해결하기 위해서는 ProductCard로 가서 너비, 높이를 정해줘야 한다.

fit: BoxFit.cover를 주면 최대한의 사이즈를 차지시킬 수 있음.
좌우가 좀 잘렸지만 정사각형이 된 것을 볼 수 있다.

그리고 이미지 모서리도 둥글게 깎아줘야 한다.
ClipRRect로 감싸주고 borderRadius 주기.


짠!!!



③ 메뉴 설명 넣기
메뉴 사진 옆에 글자는 어떻게 넣을까?
현재 ClipRRect가 왼쪽 끝에 붙어있는 상태이다. 그럼 그 옆에 남는 공간에 글자를 넣어줘야 하는데,
그러기 위해서는 Expanded로 감싸주면 된다.


💣 트러블이슈

제목, 내용, 가격 Text 컴포넌는 모두 위아래로 같은 간격으로 나뉘어져야 함.
그래서 mainAxisAlignment: MainAxisAlignment.spaceBetween 을 줬으나 바뀌지 않음...

칼럼에 색깔을 줘서 확인해보자.
빨간색 공간만큼만 차지 중이라서 여기서 spaceBetween을 해봤자,
현재 배치된 게 맞다고 생각하고 바뀌지 않게 된다.

왜 이럴까?
이유는 Row 컴포넌트 안에 넣은 값(Children)들은 각각 고유의 높이를 갖게 됨!
이건 위젯의 본능이라고 할 수 있다.
.

그래서 이미지를 보여주는 부분이 더 높은 크기를 차지하고 있더라도
나머지 부분은 각 위젯에 알맞는 사이즈를 차지하게 되는 것.

내가 원하는 건 일단 빨간색 공간이 이미지 위아래 선과 같아야 하고,
각각 내용 사이 간격도 일정해야 되는 것이기 때문에
이 문제를 해결하기 위해 Row를 IntrinsicHeight로 감싸준다.


  • product_card.dart 전체 코드
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_actual/common/const/colors.dart';

class ProductCard extends StatelessWidget {
  const ProductCard({super.key});

  
  Widget build(BuildContext context) {
    return IntrinsicHeight(
      child: Row(
        children: [
          ClipRRect(
            borderRadius: BorderRadius.circular(8),
            child: Image.asset(
              'asset/img/food/ddeok_bok_gi.jpg',
              width: 110,
              height: 110,
              fit: BoxFit.cover,
            ),
          ),
          const SizedBox(width: 16),
          const Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                // 제목
                Text(
                  '떡볶이',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
                ),
                // 내용
                Text(
                  '전통 떡볶이의 정석! \n아주 맛있어요! 처음 드시는 분들에게 강추합니다~',
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(
                    fontSize: 14,
                    color: BODY_TEXT_COLOR,
                  ),
                ),
                // 가격
                Text(
                  '₩10000',
                  textAlign: TextAlign.right,
                  style: TextStyle(
                      fontSize: 12,
                      color: PRIMARY_COLOR,
                      fontWeight: FontWeight.w500),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

  • restaurant_detail_screen.dart 전체 코드
import 'package:flutter/material.dart';
import 'package:flutter_actual/common/layout/default_layout.dart';
import 'package:flutter_actual/product/component/product_card.dart';
import 'package:flutter_actual/restaurant/component/restaurant_card.dart';

class RestaurantDetailScreen extends StatelessWidget {
  const RestaurantDetailScreen({super.key});

  
  Widget build(BuildContext context) {
    return DefaultLayout(
      title: '불타는 떡볶이',
      child: Column(
        children: [
          RestaurantCard(
            image: Image.asset('asset/img/food/ddeok_bok_gi.jpg'),
            name: '불타는 떡볶이',
            tags: const ['떡볶이', '매움', '치즈'],
            ratingsCount: 100,
            deliveryTime: 30,
            deliveryFee: 3000,
            ratings: 4.76,
            isDetail: true,
            detail: '맛있는 떡볶이',
          ),
          const Padding(
            padding: EdgeInsets.symmetric(horizontal: 16),
            child: ProductCard(),
          ),
        ],
      ),
    );
  }
}



현재까지 최종적인 결과 화면

profile
호떡 신문지에서 개발자로 환생

0개의 댓글