본문 바로가기

코딩강의/expense_tracker(플러터-유데미)

~104. Using Icons & Formatting Dates

1. 현재까지 파일 트리

2. 흐름

- main.dart

import 'package:flutter/material.dart';

import 'package:expense_tracker/wigets/expenses.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Expenses(),
    ),
  );
}

main에서 Expenses를 호출함

 

-Expenses.dart(widgets폴더)

import 'package:expense_tracker/wigets/expenses_list/expenses_list.dart';
import 'package:flutter/material.dart';

import 'package:expense_tracker/models/expense.dart';

class Expenses extends StatefulWidget {
  const Expenses({super.key});

  @override
  State<Expenses> createState() {
    return _ExpensesState();
  }
}

class _ExpensesState extends State<Expenses> {
  final List<Expense> _registeredExpenses = [
    Expense(
      title: 'Flutter Course',
      amount: 19.99,
      date: DateTime.now(),
      category: Category.work,
    ),
    Expense(
      title: 'Cinema',
      amount: 15.69,
      date: DateTime.now(),
      category: Category.leisure,
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          const Text('The chart'),
          Expanded(child: ExpensesList(expenses: _registeredExpenses)),
        ],
      ),
    );
  }
}

1) 리렌더링할 화면이기 때문에 stateful

2) 더미 데이터인 _registeredExpenses 리스트 생성, 이때 각 배열 값은 Expense 모델 값임

3) ExpensesList 위젯으로 값을 나열시켜줌, 이 때 더미 데이터를 전달. 그리고 Expanded를 통해 화면을 늘려줌으로써 데이터가 화면에 보여지게됨.

 

- expense.dart (models폴더)

import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import 'package:intl/intl.dart';

final formatter = DateFormat.yMd();

const uuid = Uuid();

enum Category { food, travel, leisure, work }

const categoryIcons = {
  Category.food: Icons.lunch_dining,
  Category.travel: Icons.flight_takeoff,
  Category.leisure: Icons.movie,
  Category.work: Icons.work,
};

class Expense {
  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);
  }
}

1) intl 을 dart패키지에서 다운받아서 날짜를 이쁘게 포매팅함. (하단 getter 부분)

2) enum을 사용해서 휴먼에러가 생기지 않도록, 카테고리 항목을 사전에 지정해주고, 카테고리 아이콘도 그에따라 사전에 세팅해둠.

3) id 값은 uuid라는 dart패키지를 다운받아서 랜덤하게 id값이 부여되게 초기화해줌.

 

- expenses_list.dart(wigets/expenses_list폴더)

import 'package:expense_tracker/wigets/expenses_list/expense_item.dart';
import 'package:flutter/material.dart';

import 'package:expense_tracker/models/expense.dart';

class ExpensesList extends StatelessWidget {
  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]));
  }
}

1) Expenses.dart에서 쓰이는 위젯으로, expenses 배열 값을 받음(Expense모델)

2) ListView를 통해 리스트의 값(배열 값)을 하나씩 나열해줄 수 있음. 그리고 각 값은 ExpenseItem 위젯으로 보여줌.

 

- expense_item.dart

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: 16,
        ),
        child: Column(
          children: [
            Text(expense.title),
            const SizedBox(height: 4),
            Row(
              children: [
                Text('\$${expense.amount.toStringAsFixed(2)}'),
                const Spacer(),
                Row(
                  children: [
                    Icon(categoryIcons[expense.category]),
                    const SizedBox(width: 8),
                    Text(expense.formattedDate),
                  ],
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

1) Expense 리스트 값을 받고 (Expense모델) 해당 값들을 이용해 하나씩 화면에 보여주는 구조

2) Card 위젯을 통해 카드형식으로 보여 줄 수 있음.

3) Spacer는 중간에 간격을 넣어주는 역할

4) 아이콘부분은 Expense모델에서 세팅한 값중에 고르게 되어 있음

5) 그 밑에 Text부분 formattedDate는 Expense모델에 있는 getter 를 활용한 것. (method를 사용하여 ()를 해도 되나 get xxx로 해서 ()를 생략 해도됨)

 

- 결과 화면