1. Introduction
지금까지, 위의 화면을 만들었으며, widgets을 저장할 수 있는 폴더를 생성해서 담아두도록 하자.
- lib
|-models
|-widgets
|-expense\_item.dart
|-expenses\_list.dart
현재까지 우리는 아래의 class를 정의내리고 살펴보았다. 그리고 이번 시간에 우리가 정의내릴 class는 바로 Expense Item이다. 자세한 설명은 아래의 내용을 참조할 것.
Expense (일반 Class) | 각 Expense가 가져야할 목록들을 지정하는 클래스 - title - amount - date - category - uuid |
Expenses (StatefulWidget) | - State class에 현재까지 user가 등록한 expense를 모아놓은 list가 존재함. - Build-> body -> Column ->children option에 ExpenseList class를 가지고옴 |
ExpenseList (StatelessWidget) | ExpenseList는 Expenses class에서 보내온 List<Expense>을 매개변수로 받으면서, 각각의 Expense 목록을 화면에 보여주는 역할을 함. (ListView.builder가 이 역할을 수행함) |
ExpenseItem(StatelessWidget) | ExpenseList는 각 expense의 목록을 변수로 받는다. 다만 추후에 더 자세하게 알아볼 예정이지만, ExpesenList에서 보내지는 각 expense widget class 객체를, 각각의 item들을 더 stylish하게 Design하는 Widget class라고 생각하면 된다. |
expense_item의 widget class는 아래같이 정의내려 진다.
import 'package:flutter/material.dart';
import 'package:expense\_tracker/models/expense.dart';
class ExpenseItem extends StatelessWidget{
const ExpenseItem(this.expense,{super.key});
final Expense expense;
@override
Widget build(BuildContext context) {
return Card(child:Text(expense.title));
}
}
이전에 정의내렸던 expense_list.dart 또한 widgets folder로 이동을 시킨다. 그리고 아래와 같이, 약간의 수정을 해준다. expense object를 ExpenseItem의 매개변수로 전달해주면, 아래의 이미지와 같이 아래의 'Card'모양이 생성된다.
import 'package:expense_tracker/widgets/expense_item.dart';
import 'package:flutter/material.dart';
import 'package:expense_tracker/models/expense.dart';
class ExpensesList extends StatelessWidget{
//initialize constructor
const ExpensesList({super.key,required this.expenses,});
final List<Expense>expenses;
@override
Widget build(BuildContext context){
return ListView.builder(itemCount:expenses.length ,
itemBuilder: (ctx,index)=>ExpenseItem(expenses[index])
);
}
}
2. Additional Modifications to 'expense_item' widget
2.1 Padding
위의 Card 구조의 padding을 담당하는 부분은 Card 가 가지고 있지 않기때문에, 우리는 refractor을 통해서, padding을 조정해줘야 한다.
class ExpenseItem extends StatelessWidget{
const ExpenseItem(this.expense,{super.key});
final Expense expense;
@override
Widget build(BuildContext context) {
return Card(
child:Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 15
),
child: Text(expense.title),
)
);
}
}
2. Row and Column
이전 프로젝트에서도 살펴보왔듯이, Column에 space를 주는 것은 const SiedBox였다.그렇다면 Row는 어떻게 사용해야 할까? Row는 Spacer를 사용해서 띄어쓰기를 사용할 수 있다.
*한 가지 추가사항으로 Row() 항목을 추가하고 Spacer 다음에 또 다른 항목을 추가하고 싶을 때는 Row() 사용해서 추가한다. *
import 'package:flutter/material.dart';
import 'package:expense\_tracker/models/expense.dart';
class ExpenseItem extends StatelessWidget{
const ExpenseItem(this.expense,{super.key});
final Expense expense;
@override
Widget build(BuildContext context) {
return Card(
child:Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 15
),
child: Column(children: [
Text(expense.title),
const SizedBox(height:4),
Row(children: [
//toStringsAsFixed acting to limit the decimal size
Text(expense.amount.toStringAsFixed(2)),
const Spacer(),
#추가사항시 Row를 추가해서 사용한다.
Row(children: [
const Icon(Icons.alarm),
const SizedBox(width:8),
Text(expense.date.toString()),
],)
],)
],)
)
);
}
}
3. Using Icons and Formatting Dates
3.1 Icons
expense.dart를 돌아가보도록 하자. 우리는 이전에 Category항목에 'food,travel,leisure,work'를 작성했었다. 그럼 이번에는 각각의 항목에다가 icond를 집어넣는것은 어떨까? 이는 Icons class를 통해서 구현된다.
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
// make uuid unresulable
const uuid= Uuid();
enum Category {food,travel,leisure,work}
const categoryIcon={
Category.food:Icons.lunch_dining,
Category.travel:Icons.flight_takeoff,
Category.leisure:Icons.movie,
Category.work:Icons.work,
};
3.2 Formatting Dates
위의 화면을 보면, Date 정보에서 초단위가 너무 길게 나오는 모습을 볼 수 있다. 이건 보기에도 그리고 사용자의 app 사용경험에 큰 지장을 줄 수 있기에, 우리는 Date를 조정하는 방법을 여기서 알아보도록 하자.
flutter에서 Date를 조정하는 방법은 상당히 귀찮을 수 있어서, 우린 외부 library를 사용해서, Date를 조작해보도록 한다."
flutter pub add intl
Intl에서 제공하는 DateFormat과 그에 해당되는 option을 통해서 Date를 조작할 수 있는데, 우리는 "yMd"를 사용하도록 하자.
//formatter
final formatter=DateFormat.yMd();
class Expense{
//constructor;retrieve arguments
Expense({
required this.title,
required this.amount,
required this.date,
required this.category,
}): id=uuid.v4();
final String id;
final String title;
final double amount;
final DateTime date;
final Category category;
String get formattedDate{
return formatter.format(date);
}
}
위와 같이 정의를 내린 후에, expense_item.dart에 가서 Icon,Date를 조정하도록 하자.
class ExpenseItem extends StatelessWidget{
const ExpenseItem(this.expense,{super.key});
final Expense expense;
@override
Widget build(BuildContext context) {
return Card(
child:Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 15
),
child: Column(children: [
Text(expense.title),
const SizedBox(height:4),
Row(children: [
//toStringsAsFixed acting to limit the decimal size
Text(expense.amount.toStringAsFixed(2)),
const Spacer(),
Row(children: [
Icon(categoryIcons[expense.category]),
const SizedBox(width:8),
Text(expense.formattedDate),
],)
'Front-End > Flutter_Project_02_Expense Tracker' 카테고리의 다른 글
Tracker6. Udemy Flutter 강의를 통한 Project - Expense Tracker (0) | 2024.12.17 |
---|---|
5. Udemy Flutter 강의를 통한 Project - Expense Tracker (0) | 2024.12.13 |
4. Udemy Flutter 강의를 통한 Project - Expense Tracker (0) | 2024.12.10 |
3. Udemy Flutter 강의를 통한 Project - Expense Tracker (0) | 2024.12.07 |
1. Udemy Flutter 강의를 통한 Project - Expense Tracker (0) | 2024.12.01 |