폴더 및 파일 만들기
pubspec.ymal 파일 설정
기본 코드 입력
앱 테마 설정
main.dart 파일 완성
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
google_fonts: ^6.2.1
intl: ^0.20.0
font_awesome_flutter: ^10.8.0
홈 화면
ImageContainer
import 'package:carrot_market_ui/screens/main_screens.dart';
import 'package:flutter/material.dart';
void main() {
runApp(CarrotMarketApp());
}
class CarrotMarketApp extends StatelessWidget {
CarrotMarketApp({super.key});
@override
Widget build(BuildContext conte000xt) {
return MaterialApp(
title: 'carrotMarket',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)
),
home: MainScreens(),
);
}
}
chatMessage
class ChatMessage {
final String sender;
final String profileImage;
final String location;
final String sendDate;
final String message;
final String? imageUri;
ChatMessage({
required this.sender,
required this.profileImage,
required this.location,
required this.sendDate,
required this.message,
this.imageUri,
});
}
// 샘플 데이터
List<ChatMessage> chatMessageList = [
ChatMessage(
sender: '당근이, ',
profileImage: 'https://picsum.photos/id/870/200/100?grayscale',
location: '대부동',
sendDate: '1일전',
message: 'developer 님,근처에 다양한 물품들이 아주 많이있습니다.',
),
ChatMessage(
sender: 'Flutter ',
profileImage: 'https://picsum.photos/id/880/200/100?grayscale',
location: '중동',
sendDate: '2일전',
message: '안녕하세요 지금 다 예약 상태 인가요?',
imageUri: 'https://picsum.photos/id/890/200/100?grayscale')
];
product
class Product {
String title;
String author;
String address;
String urlToImage;
String publishedAt;
String price;
int heartCount;
int commentsCount;
Product({
required this.title,
required this.author,
required this.address,
required this.urlToImage,
required this.publishedAt,
required this.price,
required this.heartCount,
required this.commentsCount,
});
}
// 샘플 데이터
List<Product> productList = [
Product(
title: '니트 조끼',
author: 'author_1',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_7.jpg?raw=true',
publishedAt: '2시간 전',
heartCount: 8,
price: '35000',
address: '좌동',
commentsCount: 3),
Product(
title: '먼나라 이웃나라 12',
author: 'author_2',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_6.jpg?raw=true',
publishedAt: '3시간 전',
heartCount: 3,
address: '중동',
price: '18000',
commentsCount: 1),
Product(
title: '캐나다구스 패딩조',
author: 'author_3',
address: '우동',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_5.jpg?raw=true',
publishedAt: '1일 전',
heartCount: 0,
price: '15000',
commentsCount: 12,
),
Product(
title: '유럽 여행',
author: 'author_4',
address: '우동',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_4.jpg?raw=true',
publishedAt: '3일 전',
heartCount: 4,
price: '15000',
commentsCount: 11,
),
Product(
title: '가죽 파우치 ',
author: 'author_5',
address: '우동',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_3.jpg?raw=true',
publishedAt: '1주일 전',
heartCount: 7,
price: '95000',
commentsCount: 4,
),
Product(
title: '노트북',
author: 'author_6',
address: '좌동',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_2.jpg?raw=true',
publishedAt: '5일 전',
heartCount: 4,
price: '115000',
commentsCount: 0,
),
Product(
title: '미개봉 아이패드',
author: 'author_7',
address: '좌동',
urlToImage:
'https://github.com/flutter-coder/ui_images/blob/master/carrot_product_1.jpg?raw=true',
publishedAt: '5일 전',
heartCount: 8,
price: '85000',
commentsCount: 3,
),
];
chat_container
import 'package:carrot_market_ui/components/ImageContainer.dart';
import 'package:flutter/material.dart';
import '../../../../models/chatMessage.dart';
class ChatContainer extends StatelessWidget {
final ChatMessage chatMessage;
const ChatContainer({required this.chatMessage, super.key});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey, width: 0.5))),
height: 100,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
children: [
ImageContainer(
borderRadius: 25,
imageUrl: chatMessage.profileImage,
width: 50,
height: 50,
),
const SizedBox(width: 16.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Spacer(),
Text.rich(
TextSpan(
children: [
TextSpan(
text: chatMessage.sender,
style: TextStyle(fontSize: 14),
),
TextSpan(
text: chatMessage.location,
style: TextStyle(fontSize: 12, color: Colors.grey),
),
TextSpan(
text: ' • ${chatMessage.sendDate}',
style: TextStyle(fontSize: 12, color: Colors.grey),
),
],
),
),
Text(
chatMessage.message,
overflow: TextOverflow.ellipsis,
),
const Spacer()
],
),
),
/// 이미지 추가
Visibility(
visible: chatMessage.imageUri != null,
child: ImageContainer(
width: 50,
height: 50,
borderRadius: 8,
imageUrl: chatMessage.imageUri ?? '',
),
)
],
),
),
);
}
}
chatting_screen
import 'package:carrot_market_ui/screens/chatting/components/chat_container.dart';
import 'package:flutter/material.dart';
import '../../models/chatMessage.dart';
class ChattingScreen extends StatelessWidget {
const ChattingScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('채팅'),
bottom: PreferredSize(
preferredSize: Size.fromHeight(0.5),
child: Divider(thickness: 0.5, height: 0.5, color: Colors.grey),
),
),
body: ListView(
children: List.generate(
chatMessageList.length,
(index) => ChatContainer(chatMessage: chatMessageList[index]),
),
),
);
}
}
product_detail
import 'package:carrot_market_ui/models/product.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ProductDetail extends StatelessWidget {
final Product product;
const ProductDetail({required this.product, super.key});
@override
Widget build(BuildContext context) {
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.title,
style: TextStyle(fontSize: 16),
),
const SizedBox(height: 4.0),
Text(
'${product.address} ‧ ${product.publishedAt} ',
style: TextStyle(fontSize: 13),
),
const SizedBox(height: 4.0),
Text(
'${numberFormat(product.price)} 원',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Visibility(
visible: product.commentsCount > 0,
child: _buildIcons(
product.commentsCount,
CupertinoIcons.chat_bubble_2,
),
),
const SizedBox(width: 8.0),
Visibility(
visible: product.heartCount > 0,
child: _buildIcons(
product.heartCount,
CupertinoIcons.heart,
),
),
],
),
],
),
);
}
}
Widget _buildIcons(int count, IconData iconData) {
return Row(
children: [
Icon(iconData, size: 14.0),
const SizedBox(
width: 4.0,
),
Text('${count}')
],
);
}
String numberFormat(String price) {
final formatter = NumberFormat('#,###');
return formatter.format(int.parse(price));
}
product_item
import 'package:carrot_market_ui/models/product.dart';
import 'package:flutter/material.dart';
class ProductItem extends StatelessWidget {
final Product product;
const ProductItem({required this.product, super.key});
@override
Widget build(BuildContext context) {
return Container(
height: 135.0,
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.network(
product.urlToImage,
width: 115,
height: 115,
fit: BoxFit.cover,
),
),
],
),
);
}
}
home
import 'package:carrot_market_ui/screens/home/components/product_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../models/product.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: [
const Text('좌동'),
const SizedBox(width: 4.0),
const Icon(CupertinoIcons.chevron_down),
],
),
actions: [
IconButton(
onPressed: () {},
icon: Icon(CupertinoIcons.search),
),
IconButton(
onPressed: () {},
icon: Icon(CupertinoIcons.list_dash),
),
IconButton(
onPressed: () {},
icon: Icon(CupertinoIcons.bell),
)
],
// 구분선
bottom: PreferredSize(
preferredSize: Size.fromHeight(0.5),
child: Divider(thickness: 0.5, height: 0.5, color: Colors.grey,),
),
),
body: ProductItem(product: productList[0],),
);
}
}
main_screens
import 'package:carrot_market_ui/screens/chatting/chatting_screen.dart';
import 'package:carrot_market_ui/screens/home/home.dart';
import 'package:flutter/material.dart';
class MainScreens extends StatefulWidget {
const MainScreens({super.key});
@override
State<MainScreens> createState() => _MainScreensState();
}
class _MainScreensState extends State<MainScreens> {
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
// 최대 5개까지 관리 함
body: IndexedStack(
index: _selectedIndex,
children: [
HomeScreen(),
// 1번 인덱스
ChattingScreen(),
],
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '홈'
),
BottomNavigationBarItem(
icon: Icon(Icons.chat_bubble),
label: '채팅'
),
],
onTap: (index){
setState(() {
_selectedIndex = index;
});
},
currentIndex: _selectedIndex,
),
),
);
}
}
main
import 'package:carrot_market_ui/screens/main_screens.dart';
import 'package:flutter/material.dart';
void main() {
runApp(CarrotMarketApp());
}
class CarrotMarketApp extends StatelessWidget {
CarrotMarketApp({super.key});
@override
Widget build(BuildContext conte000xt) {
return MaterialApp(
title: 'carrotMarket',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)
),
home: MainScreens(),
);
}
}
'Flutter' 카테고리의 다른 글
[Flutter] Flutter에서 Key의 역할과 필요성 (0) | 2024.11.14 |
---|---|
[Flutter] Flutter의 위젯과 Element 트리 그리고 Key의 역할과 사용 방법 (1) | 2024.11.14 |
[Flutter] Flutter에서의 위젯 생명 주기 (0) | 2024.11.14 |
[Flutter] GestureDetector 위젯 (0) | 2024.11.14 |
[Flutter] 개발자 모드 (0) | 2024.11.14 |