728x90
반응형
쇼핑 카트 앱 만들기
image -> stateFull위젯
container - >
테스트 코드 만들어 보기
1단계 > test코드
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//이벤트가 일어나면 다시 화면을 그려야 한다.(reRendering)
class MyApp extends StatefulWidget {
MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
//현재시간 상태를 저장하는 변수
String timeOfDay = '낮';
@override
Widget build(BuildContext context) {
print('전체 build() 메서드 호출 ');
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Container(
color: Colors.blue,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 1,
child: InkWell(
onTap: () {
print('이벤트 리스너 등록');
timeOfDay = (timeOfDay == '낮' ? '밤' : '낮');
print('현재 상태 값 : ${timeOfDay}');
// 화면을 새롭게 갱신하라고 명령해주어야 한다.
setState(() {
//이 메서드 실행시 build가 다시 호출됨
print('화면 다시 그려줘 --> build() 재 호출한다.');
});
},
child: Container(
alignment: Alignment.center,
color: (timeOfDay == '낮') ? Colors.green : Colors.black,
child: Text(
timeOfDay,
style: TextStyle(
fontSize: 25,
color: (timeOfDay == '밤'
? Colors.white
: Colors.black)),
),
),
),
),
// 이미지
Expanded(
flex: 1,
child: FlutterLogo(
size: 300,
style: FlutterLogoStyle.markOnly,
textColor: Colors.red,
),
)
],
),
),
),
),
);
}
}
2단계 > 화면이 다시 랜더링 되는 부분을 줄여보자 => 리팩토링
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// 이벤트가 일어 나면 다시 화면을 그려야 한다.
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
print('전체 build() 메서드 호출 : 111111111111111111111111111');
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Container(
color: Colors.blue,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 1,
child: TodayWidget(),
),
// 이미지
Expanded(
flex: 1,
child: FlutterLogo(
size: 300,
style: FlutterLogoStyle.markOnly,
textColor: Colors.red,
),
)
],
),
),
),
),
);
}
}
class TodayWidget extends StatefulWidget {
const TodayWidget({super.key});
@override
State<TodayWidget> createState() => _TodayWidgetState();
}
class _TodayWidgetState extends State<TodayWidget> {
//현재시간 상태를 저장하는 변수
String timeOfDay = '낮';
@override
Widget build(BuildContext context) {
print('_TodayWidgetState build() 메서드 호출 ');
return InkWell(
onTap: () {
print('이벤트 리스너 등록');
timeOfDay = (timeOfDay == '낮' ? '밤' : '낮');
print('현재 상태 값 : ${timeOfDay}');
// 화면을 새롭게 갱신하라고 명령해주어야 한다.
setState(() {
//이 메서드 실행시 build가 다시 호출됨
print('화면 다시 그려줘 --> build() 재 호출한다.');
});
},
child: Container(
alignment: Alignment.center,
color: (timeOfDay == '낮') ? Colors.green : Colors.black,
child: Text(
timeOfDay,
style: TextStyle(
fontSize: 25,
color: (timeOfDay == '밤' ? Colors.white : Colors.black)),
),
),
);
}
}
분리한 부분의 buil만 리랜더링 되는것을 볼 수 있다.
/flutter ( 8276): 전체 build() 메서드 호출 : 111111111111111111111111111
I/flutter ( 8276): _TodayWidgetState build() 메서드 호출
D/ProfileInstaller( 8276): Installing profile for com.example.flutter_shopping_cart_app
I/flutter ( 8276): 이벤트 리스너 등록
I/flutter ( 8276): 현재 상태 값 : 밤
I/flutter ( 8276): 화면 다시 그려줘 --> build() 재 호출한다.
I/flutter ( 8276): _TodayWidgetState build() 메서드 호출
D/EGL_emulation( 8276): app_time_stats: avg=2834.68ms min=4.58ms max=5664.78ms count=2
I/flutter ( 8276): 이벤트 리스너 등록
I/flutter ( 8276): 현재 상태 값 : 낮
I/flutter ( 8276): 화면 다시 그려줘 --> build() 재 호출한다.
I/flutter ( 8276): _TodayWidgetState build() 메서드 호출
I/flutter ( 8276): 이벤트 리스너 등록
I/flutter ( 8276): 현재 상태 값 : 밤
I/flutter ( 8276): 화면 다시 그려줘 --> build() 재 호출한다.
I/flutter ( 8276): _TodayWidgetState build() 메서드 호출
쇼핑몰 앱 만들기
순서
1. lib/constants.dart 파일 만들기
2. lib/theme.dart 파일 만들기
3. main.dart 기본 코드 설계하기
4. 쇼핑카트 헤더 만들기
5. main 앱바 추가
6. 쇼핑카트 바디 만들기
constants.dart
import 'package:flutter/material.dart';
const kPrimaryColor = MaterialColor(
0xFFeeeeee,
<int, Color>{
50: Color(0xFFeeeeee),
100: Color(0xFFeeeeee),
200: Color(0xFFeeeeee),
300: Color(0xFFeeeeee),
400: Color(0xFFeeeeee),
500: Color(0xFFeeeeee),
600: Color(0xFFeeeeee),
700: Color(0xFFeeeeee),
800: Color(0xFFeeeeee),
900: Color(0xFFeeeeee),
},
);
const kSecondaryColor = Color(0xFFc6c6c6); // 기본 버튼 색
const kAccentColor = Color(0xFFff7643); // 활성화 버튼 색
thmem.dart => 테마
import 'package:flutter/material.dart';
import 'package:shopping_cart_app/constants.dart';
ThemeData mTheme() {
return ThemeData(
primarySwatch: kPrimaryColor,
scaffoldBackgroundColor: kPrimaryColor,
);
}
main.dart 기본 코드 설계하기
import 'package:flutter/material.dart';
import 'package:flutter_shopping_cart_app/components/shopping_cart_header.dart';
import 'package:flutter_shopping_cart_app/pages/shop_cart_page.dart';
import 'package:flutter_shopping_cart_app/theme.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: mTheme(),
home: ShopCartPage(),
);
}
} //end of Page
쇼핑카트 헤더 만들기
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_shopping_cart_app/constants.dart';
class ShoppingCartHeader extends StatefulWidget {
const ShoppingCartHeader({super.key});
@override
State<ShoppingCartHeader> createState() => _ShoppingCartHeaderState();
}
class _ShoppingCartHeaderState extends State<ShoppingCartHeader> {
// 1. 상태
int selectId = 0;
List<String> selectPic = [
'assets/images/p1.jpeg',
'assets/images/p2.jpeg',
'assets/images/p3.jpeg',
'assets/images/p4.jpeg',
];
//2.상태는 행위를 통해서 변경해야한다.
void changeSelectId(int sId) {
setState(() {
selectId = sId;
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
AspectRatio(
aspectRatio: 5 / 3,
child: Image.asset(
selectPic[selectId],
fit: BoxFit.cover,
),
),
const SizedBox(height: 25.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildHeaderSelectContainer(Icons.pedal_bike, 0),
_buildHeaderSelectContainer(Icons.motorcycle, 1),
_buildHeaderSelectContainer(CupertinoIcons.car, 2),
_buildHeaderSelectContainer(CupertinoIcons.airplane, 3),
],
)
],
),
);
}
Widget _buildHeaderSelectContainer(IconData micon, int sId) {
return InkWell(
child: Container(
width: 70,
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: (selectId == sId) ? kAccentColor : kSecondaryColor,
),
child: IconButton(
onPressed: () {
//메소드로 호출해서 사용함
changeSelectId(sId);
},
icon: Icon(
micon,
color: Colors.black,
),
),
),
);
}
}
main app바 추가하기
import 'package:flutter/material.dart';
import 'package:flutter_shopping_cart_app/components/shopping_cart_header.dart';
class ShopCartPage extends StatelessWidget {
const ShopCartPage({super.key});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: _buildAppBar(),
body: Column(
children: [
ShoppingCartHeader(),
],
),
),
);
}
AppBar _buildAppBar() {
return AppBar(
leading: IconButton(onPressed: () {}, icon: Icon(Icons.arrow_back)),
actions: [IconButton(onPressed: () {}, icon: Icon(Icons.shopping_cart))],
);
}
} //end of page
main body 부분
import 'package:flutter/material.dart';
class ShoppingCartBody extends StatelessWidget {
ShoppingCartBody({super.key});
final List<Color> colorList = [
Colors.black,
Colors.green,
Colors.orange,
Colors.grey,
Colors.white
];
@override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildBodyNameAndPrice('Urban Soft AL 10.0', '699'),
_buildBodyRatingAndReviews(4, 20),
_buildBodyOption(),
_buildBodyButtonToCart(),
],
),
),
),
);
} //end of build
//1.상품의 이름과 가격을 표시
Widget _buildBodyNameAndPrice(String name, String price) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
name,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
),
Text('\$ ${price}'),
],
);
}
// 2. 별점 리뷰 카운트
Widget _buildBodyRatingAndReviews(int rate, int count) {
return Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Row(children: [
...List.generate(
5,
(index) {
if (index < rate) {
return Icon(
Icons.star,
color: Colors.amber,
);
} else {
return Icon(Icons.star_border, color: Colors.amber);
}
},
),
Spacer(),
Text('review ( ${count} )'),
])
]);
}
//3. 색상 옵션 선택
Widget _buildBodyOption() {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Color Options'),
const SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(colorList.length,
(index) => _buildBodyOptionContainer(colorList[index])))
],
);
}
//4.색상 옵션 위젯을 만드는 함수
Widget _buildBodyOptionContainer(Color mcolor) {
return Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Stack(
children: [
Positioned(
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
border: Border.all(color: Colors.black),
),
),
),
Positioned(
top: 3,
left: 3,
child: Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: mcolor,
borderRadius: BorderRadius.all(Radius.circular(50)),
),
),
),
],
),
);
}
//5.add to cart 버튼
Widget _buildBodyButtonToCart() {
return TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.orange,
foregroundColor: Colors.white,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
minimumSize: Size(400, 60)),
onPressed: () {},
child: Text('Add to Cart'),
);
}
} //end of body
728x90
반응형
'Flutter' 카테고리의 다른 글
[flutter20] CallBack 함수 (0) | 2025.01.14 |
---|---|
[flutter19] LoginApp 만들기 (0) | 2025.01.13 |
[Flutter00] Flutter 기초다지기3 _ List (0) | 2025.01.08 |
댓글