Skip to content

1단계 buildMethod를 Widget으로 분리 #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: testrace
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,51 @@ A few resources to get you started if this is your first Flutter project:
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.


# 🚀 1단계 - buildMethod를 Widget으로 분리하기

### 요구사항
- [ ] buildMethod로 구현된 코드들을 Widget으로 구현
- [x] 가게명 위젯
- [x] 생성자로 가게명을 주입 받는다.
- [x] 상품 위젯
- [x] 생성자로 상품명(메뉴명)을 주입 받는다.
- [x] 생성자로 상품설명을 주입 받는다.
- [x] 생성자로 가격을 주입 받는다.
- [x] 더 담으러 가기 버튼
- [x] 결제 금액 위젯
- [x] 결제하기 버튼
- [x] Stateless Widget으로 구현
- [x] 데이터를 생성자로 전달 받아서 다른 음식점, 다른 메뉴도 표시할 수 있도록 수정
- [x] class 네이밍은 자유롭게 하되, 의미 파악이 명확하도록 작성해주세요.



### note
- Dart
- DO name libraries, packages, directories, and source files using lowercase_with_underscores.
- 라이브러리, 패키지, 디렉토리, 소스파일은 소문자와 언더스코어를 사용한다. [링크](https://dart.dev/guides/language/effective-dart/style#do-name-libraries-and-source-files-using-lowercase_with_underscores)
- snake case 라는 표현을 안쓰네..?
- Flutter
- 플러터 위젯을 사용하기 위해서는 반드시 상단에 위젯을 import를 해주어야 한다. `Dart != Flutter`
- `import 'package:flutter/material.dart';`
- `import 'package:flutter/cupertino.dart';`
- meterial, cupertino는 위젯을 관리하는 테마? 같은 것 같다.. 멀티 플랫폼을 지원하기 위한.
- 매번 import를 직접 입력해줘야하는 불편함.
- Q. 두 가지 import 방식의 차이점은? 멀티 모듈을 활용한 외부 프로젝트도 import 가능?
- `import 'package:cart_sample/component/button_add_more.dart';`
- `import 'component/button_add_more.dart.dart';`
- 클래스를 만드니 key를 주입받는 생성자를 추가하라는데 Key는 위젯에서 사용하는 값으로 확인.
- key를 왜 사용하는지, 어떤 방식으로 사용해야 하는지 공부할 필요 있음!
- 클래스 생성자
- 자바와는 다르게(?) 멤버 변수에 할당하는 로직이 없다!
- 생성자에서 인자를 여러개 받도록 정의된 경우 생성자를 호출할 때 인자명을 명시해줘야 한다.

### 피드백
- [x] 금액, 이미지 경로 등 하드코딩을 생성자를 통해 주입 받을 수 있도록 변경
- [x] 가게명, 가게 이미지 경로
- [x] 변수명 앞에 `_`를 붙여서 private 변수로 정의
- [x] 가게명, 가게 이미지 경로
- [x] 버튼을 상속하지 않고 구현
- [x] 특정 클래스에만 사용할 수 있도록 지정 (part, part of)
278 changes: 19 additions & 259 deletions lib/cart_screen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

part 'component/button_billing.dart';
part 'component/billing.dart';
part 'component/button_add_more.dart';
part 'component/store_name.dart';
part 'component/menu.dart';

class CartScreen extends StatefulWidget {
const CartScreen({Key? key}) : super(key: key);
Expand All @@ -10,6 +17,8 @@ class CartScreen extends StatefulWidget {
class _CartScreenState extends State<CartScreen> {
@override
Widget build(BuildContext context) {
const billing = Billing(18000, 3000);

return Scaffold(
backgroundColor: const Color.fromRGBO(246, 246, 246, 1.0),
appBar: AppBar(
Expand All @@ -30,16 +39,20 @@ class _CartScreenState extends State<CartScreen> {
SizedBox(
height: 10,
),
_buildStoreName(),
StoreName('치킨 잠실점', 'images/chickenCartoonImage.jpg'),
SizedBox(
height: 1,
),
_buildMenu(),
Menu(
'후라이드 치킨',
'• 찜 & 리뷰 약속 : 참여. 서비스음료제공',
'${billing.totalPrice()}원',
),
SizedBox(
height: 1,
),
_buildAddMore(),
_buildBilling(),
ButtonAddMore(),
billing,
],
),
bottomNavigationBar: Container(
Expand All @@ -51,266 +64,13 @@ class _CartScreenState extends State<CartScreen> {
horizontal: 20,
vertical: 10,
),
child: ElevatedButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 25,
height: 25,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Center(
child: Text(
'1',
style: TextStyle(
color: Color.fromRGBO(44, 191, 188, 1.0),
fontWeight: FontWeight.bold,
),
),
),
),
SizedBox(
width: 7,
),
Text(
'21,000원 배달 주문하기',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Color.fromRGBO(44, 191, 188, 1.0),
),
),
child: ButtonBilling(
billing.totalPrice(),
onPressed: () {},
),
),
),
),
);
}

Widget _buildStoreName() {
return Container(
color: Colors.white,
height: 70,
child: Row(
children: [
SizedBox(
width: 20,
),
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.asset(
'images/chickenCartoonImage.jpg',
width: 35,
height: 35,
),
),
SizedBox(
width: 10,
),
Text(
'치킨 잠실점',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
)
],
),
);
}

Widget _buildMenu() {
return Container(
color: Colors.white,
child: Column(
children: [
Row(
children: [
SizedBox(
width: 20,
),
Text(
'후라이드 치킨',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
),
),
Spacer(),
IconButton(
icon: Icon(
Icons.close,
color: Colors.grey,
),
onPressed: () {},
),
],
),
Row(
children: [
SizedBox(
width: 20,
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey.withOpacity(0.3),
width: 1,
),
borderRadius: BorderRadius.circular(12),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.asset(
'images/chicken.png',
width: 70,
height: 70,
fit: BoxFit.cover,
),
),
),
SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'• 찜 & 리뷰 약속 : 참여. 서비스음료제공',
style: TextStyle(
color: Color.fromRGBO(125, 125, 125, 1.0),
),
),
Text('18,000원'),
],
),
],
),
SizedBox(
height: 20,
),
],
),
);
}

Widget _buildAddMore() {
return GestureDetector(
onTap: () {},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
color: Colors.grey.withOpacity(0.3),
width: 2,
),
),
),
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.add),
Text(
'더 담으러 가기',
style: TextStyle(fontSize: 17),
),
],
),
),
);
}

Widget _buildBilling() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
color: Colors.grey.withOpacity(0.3),
width: 2,
),
),
),
child: Column(
children: [
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
children: [
Text('총 주문금액'),
Spacer(),
Text('18,000원'),
],
),
),
SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
children: [
Text(
'배탈팁',
style: TextStyle(
fontSize: 16,
),
),
Spacer(),
Text(
'3,000원',
style: TextStyle(
fontSize: 16,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(20),
child: Divider(
color: Colors.grey,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
children: [
Text(
'결제예정금액',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Spacer(),
Text(
'21,000원',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
),
SizedBox(
height: 20,
),
],
),
);
}
}
Loading