일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 러닝핏습관챌린지
- 내일배움카드인강
- 안드로이드
- Flutter
- 습관챌린지
- 내일배움투어
- 러닝핏인강
- 국비코딩
- 개발
- 웹개발
- 인사이드아웃
- 국비지원코딩
- 고용노동부국비지원
- 개발자부트캠프
- 앱개발
- 부트캠프
- 내일배움카드사용처
- 웅진씽크빅
- ios
- 스나이퍼팩토리
- 코딩국비지원
- 국비지원파이썬
- K디지털기초역량훈련
- K디지털크레딧
- IT개발캠프
- 플러터
- Udemy
- 0원코딩인강
- 러닝핏
- 유데미
- Today
- Total
매일 땡기는 마라 코딩
[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 3일차 과제 - 스타벅스 클론코딩 본문
요구사항
- 음료 이미지는 CircleAvatar를 사용하며 48의 반지름크기를 갖는다.
- 음료 영문명의 font size는 14pt이며 회색으로 w200의 굵기를 가진다.
- 음료의 정보를 보여주는 위젯을 만들고, 이름은 DrinkTile로 한다.
사전 지식
"bottomSheet"
하단 메뉴나 액션을 표시하기 위해 사용한다.
스크롤에 따라 위치가 변하지 않는다.
항상 볼 수 있는 Persistent BottomSheet와 일시적으로 사용하는 Modal BottomSheet로 나눌 수 있다.
높이, 색상 등을 지정할 수 있다.
"mainAxisAlignment, crossAxisAlignment"
Row, Column을 정렬하기 위해 사용한다.
Row(행)은 가로가 main이 된다.
Column(열)은 세로가 main이 된다.
mainAxisAlignment의 속성은?
- center: 가운데 정렬
- start: Row 기준 왼쪽 정렬, Column 기준 위쪽 정렬
- end: Row 기준 오른쪽 정렬, Column 기준 아래쪽 정렬
- spaceEvently: 자식 위젯 사이의 공간을 균등하게 배분
- spaceBetween: 처음, 끝 위젯을 시작과 끝에 배치하고, 사이 위젯을 균일하게 배치
- spaceAround: 처음, 끝 위젯의 앞뒤 공간을, 나머지 위젯 사이 공간의 반만큼 설정하여 배치
crossAxisAlignment의 속성은?
- center, start, end는 같음(화면에 출력되는 게 같다는 게 아닙니당)
- stretch: 좌우를 꽉 차게 배치
- baseline: 베이스 라인 기준으로 Row는 수평 정렬, Column은 수직 정렬(폰트 크기가 다를 때 유용)
bottomNavigationBar의 속성
- BottomNavigationBarType.fixed: item 4개 이상 추가 시 문제 발생을 방지하기 위해 아이템의 너비 고정(모두 동일한 너비)
- currentIndex: 현재 선택된 아이템의 인덱스를 지정
- fixedColor: 선택된 아이템의 색상 지정
그 외
- foregroundColor: Colors.색상명 - 글씨 색상 지정
- elevation: 0 - 그림자를 0으로 지정
ListView에 Padding을 지정해 주면 자식 위젯에 하나씩 Padding을 지정해 줄 필요가 없다. 꿀팁!
코드
main.dart
import 'package:assigment1/DrinkTile.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
foregroundColor: Colors.black,
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.keyboard_arrow_left),
),
actions: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.search),
),
],
),
body: Padding(
//여기다 걸면 하나하나 안 해 줘도 됨!
padding: const EdgeInsets.all(16),
child: ListView(
children: [
Text(
'new'.toUpperCase(), //소문자를 대문자로 변환
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 32,
),
),
SizedBox(
height: 16,
),
DrinkTile(
title: '골든 미모사 그린 티',
subTitle: 'Golden Mimosa Greern Tea',
price: 6100,
imgUrl: 'assets/images/item_drink1.jpeg',
),
DrinkTile(
title: '블랙 햅쌀 고봉 라떼',
subTitle: 'Black Rice Latte',
price: 6300,
imgUrl: 'assets/images/item_drink2.jpeg',
),
DrinkTile(
title: '아이스 블랙 햅쌀 고봉 라떼',
subTitle: 'Iced Black Rice Latte',
price: 6300,
imgUrl: 'assets/images/item_drink3.jpeg',
),
DrinkTile(
title: '스타벅스 튜메릭 라떼',
subTitle: 'Starbucks Turmeric Latte',
price: 6100,
imgUrl: 'assets/images/item_drink4.jpeg',
),
DrinkTile(
title: '아이스 스타벅스 튜메릭 라떼',
subTitle: 'Iced Starbucks Turmeric Latte',
price: 6100,
imgUrl: 'assets/images/item_drink5.jpeg',
),
],
),
),
bottomSheet: Container(
height: 64,
color: Colors.black87,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'주문할 매장을 선택해 주세요.',
style: TextStyle(color: Colors.white),
),
Container(
child: Icon(
Icons.keyboard_arrow_down,
color: Colors.white,
),
),
],
),
),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed, //형태 고정
currentIndex: 2, //2번 인덱스로 고정(Order)
fixedColor: Colors.green, //선택된 item의 색상 지정
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: ('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.credit_card), label: ('Pay')),
BottomNavigationBarItem(
icon: Icon(Icons.local_cafe), label: ('Order')),
BottomNavigationBarItem(
icon: Icon(
Icons.shop,
// color: Colors.black, 노가다할 뻔
),
label: ('Shop')),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz), label: ('Other')),
],
),
),
);
}
}
DrinkTile.dart
import 'package:flutter/material.dart';
class DrinkTile extends StatelessWidget {
const DrinkTile(
{super.key,
required this.title,
required this.subTitle,
required this.price,
required this.imgUrl});
final String imgUrl;
final String title;
final String subTitle;
final int price;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16),
child: Row(
children: [
CircleAvatar(
radius: 48,
backgroundImage: AssetImage(imgUrl),
),
SizedBox(
width: 16,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start, //시작점 정렬
children: [
Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
Text(
subTitle,
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.w200,
),
),
SizedBox(
height: 8,
),
Text(
// price.toString() + '원', //int를 string으로 치환
"$price원",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
],
),
],
),
);
}
}
결과
회고
다른 부분들은 다 만들었는데, 이미지가 확대된 채로 작게 잘려 나와서 왜 그런가 했더니 ListTitle을 사용하지 않고 만드는 거였다니... 예시 사진을 보고 무슨 위젯을 써야 하는지 파악하는 연습도 많이 해 봐야 할 것 같다.
아이콘도 이름 몰라서 계속 사이트에 찾아 보고, 속성도 모르는 게 많아 헤매고 ㅠ.
과정 따라가다 보면 익숙해질 거라고 믿는다...!
Bottom sheets 부분도 Material Design 사이트에서 찾긴 했으나... 사용 방법을 몰라 헤맸다는 후문.
Bottom sheets의 아이콘이 텍스트 옆에 배치되는 것도 해결 못 해서 나중에 올라온 강의 영상 보고 알았다.
근데 과제 해결할 시간 주고, 나중에 해설 영상 올라오는 거 진짜 좋은 듯.
이전에 해 본 클론 코딩은 강의 영상을 따라하는 수준 정도라, 내가 직접 생각해서 코딩하는 게 아니라 얻는 게 적은 느낌이었는데, 이런 방식이 나한테 맞는 것 같다.
추가로, 강의 중에 VSCode로 직접 쳐 본 코드는 DartPad의 기능인 Git Gists 업로드를 사용해서 기록 중이다.
cmkoi1’s gists
GitHub Gist: star and fork cmkoi1's gists by creating an account on GitHub.
gist.github.com
참고 자료
- https://m3.material.io/components/bottom-sheets/overview
- https://beomseok95.tistory.com/310
- https://dev-bak.tistory.com/13
본 후기는 유데미-스나이퍼팩토리 9주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.
#유데미 #udemy #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #웹개발 #앱개발 #플러터 #flutter #개발 #안드로이드 #ios #단기캠프
'Flutter' 카테고리의 다른 글
[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 4일차 과제 - 사칙연산 (0) | 2023.10.22 |
---|---|
[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 3일차 과제 - 유튜브 뮤직 클론코딩 (5) | 2023.10.22 |
[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 2일차 과제 (0) | 2023.09.21 |
[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 1일차 과제 (0) | 2023.09.20 |
[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] #0-2. Git (0) | 2023.09.19 |