순서
1. 화면구조 구성하기
2. 폰트, 이미지등 assets 구성하기
3. 각 화면 구성
4. 실행
1. 화면구조 구성하기
상단 AppBar
본문 Listview
본문안의 내용 Row, ClipRRect
2. 폰트, 이미지등 assets 구성하기
pubspec.yaml - 변경후에는 Pub get 버튼을 클릭하여 적용해야 한다.
name: flutter_recipe
description: Flutter Recipe App UI
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets: # assets 폴더 지정
- assets/images/
fonts: # 폰트 지정
- family: BMDOHYEON
fonts:
- asset: assets/fonts/BMDOHYEON_ttf.ttf
3. 각 화면 구성
프로젝트 파일 구조
사용된 클래스
AppBar, Icon, Text, Container, ClipRRect, Listview
AppBar : https://api.flutter.dev/flutter/material/AppBar-class.html
Icon : https://api.flutter.dev/flutter/widgets/Icon-class.html
Text : https://api.flutter.dev/flutter/dart-html/Text-class.html
Container : https://api.flutter.dev/flutter/widgets/Container-class.html
ClipRRect : https://api.flutter.dev/flutter/widgets/ClipRRect-class.html
Listview : https://api.flutter.dev/flutter/widgets/ListView-class.html
파일별 소스
components/recipe_list_item.dart
import 'dart:ui';
import 'package:flutter/material.dart';
class RecipeListItem extends StatelessWidget {
final String imageName;
final String title;
final String desc;
const RecipeListItem(this.imageName, this.title, this.desc);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10), // 세로 단격 10으로
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 3/1, // 이미지사이즈 크기를 조정 3/1 -> 3배 줄임
child: ClipRRect(
borderRadius: BorderRadius.circular(30), // 모서리 라운딩 처리
child: Image.asset( // 이미지 지정, 인자값으로 받은 이미지명을 assets에서 찾아 가져옴
"assets/images/$imageName.jpeg",
fit: BoxFit.cover, // 이미지 맞춤을 커버 형식으로
),
),
),
SizedBox(height: 5,), // 이미지와 아래 text 간격
Text(
title,
style: TextStyle(fontSize: 15),
),
Text(
desc,
style: TextStyle(color: Colors.grey, fontSize: 12),
)
],
),
);
}
}
components/recipe_menu.dart
import 'package:flutter/material.dart';
class RecipeMenu extends StatelessWidget {
const RecipeMenu({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: Row( // 메뉴 아이템들의 방향이 수평 방향이라서 row를 사용
children: [
_buildMenuItem(Icons.food_bank, "Menu1"),
SizedBox(width: 20),
_buildMenuItem(Icons.emoji_food_beverage, "Menu2"),
SizedBox(width: 20),
_buildMenuItem(Icons.fastfood, "Menu3"),
SizedBox(width: 20),
_buildMenuItem(Icons.local_pizza, "Menu4"),
],
),
);
}
}
/**
* 메뉴 아이콘을 만들기 위한 함수
*/
Widget _buildMenuItem(IconData mIcon, String iconText) {
return Container( // 데코레이션을 위해 사용
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.black12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(mIcon, color: Colors.redAccent, size: 25,),
SizedBox(height: 5,),
Text(
iconText,
style: TextStyle(color: Colors.black87, fontSize: 10),
)
],
),
);
}
components/recipe_title.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class RecipeTitle extends StatelessWidget {
const RecipeTitle({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top:20),
child: Text(
"타이틀",
style: TextStyle(fontSize: 20),
),
);
}
}
pages/recipe_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_recipe/components/recipe_list_item.dart';
import 'package:flutter_recipe/components/recipe_menu.dart';
import 'package:flutter_recipe/components/recipe_title.dart';
/**
* 하단의 리스트 페이지
*/
class RecipePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white, // 배경색 지정
appBar: _buildRecipeAppBar(), // AppBar 연결
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20), // 수평으로 여백 주기
child: ListView(
// Column 위에서 아래로 내려가는 구조
children: [
RecipeTitle(),
RecipeMenu(),
RecipeListItem("pizza", "피자 만들기", "도우를 만드는게 중요합니다. 준비물:밀가루, 피망, 치즈, "),
RecipeListItem("burger", "버거 만들기", "버거에는 감자튀김이 제일 중요하죠. 준비물:감자, 햄, "),
RecipeListItem("coffee", "커피 만들기","좋은 원두를 준비합니다. 커피머신에 원두를 넣고"),
],
),
),
);
}
}
/**
* 상단의 앱 바
*/
AppBar _buildRecipeAppBar() {
return AppBar(
title: Text("앱바 타이틀", style: TextStyle(color: Colors.black, fontSize: 15),),
backgroundColor: Colors.white, //배경색
elevation: 3.0, // 그림자 효과 조정
leading: IconButton(icon: Icon(Icons.menu), onPressed: null,),
actions: [
Icon(
CupertinoIcons.search, // 쿠퍼티노 아이콘 사용
color: Colors.black, // 아이콘 색상
),
SizedBox(width: 15,), // 공백 박스
Icon(
CupertinoIcons.heart,
color: Colors.redAccent,
),
SizedBox(width: 15,)
],
);
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_recipe/pages/recipe_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(fontFamily: "BMDOHYEON"), // pubspec.yaml에 등록한 폰트지정
home: RecipePage(), // 홈 화면으로 RecipePage
);
}
}
4. 실행
'개발 > Flutter' 카테고리의 다른 글
[Flutter] 프로필 UI 만들기 (0) | 2021.12.30 |
---|---|
[Flutter] The flutter tool cannot access the file or directory. (0) | 2021.12.29 |
[Flutter] 플러터로 개발시 유용한 pub.dev (0) | 2021.12.12 |
[Fultter] 쇼핑몰 UI 만들기 (0) | 2021.12.03 |
[Flutter] Intellij 에서 플러터 개발 환경 세팅 (1) | 2021.07.01 |
댓글