본문 바로가기

06. 앱

00025. [APP-00003] AI 음식 영양 분석 앱 개발기 #6 – 식사 기록 저장 및 영양 통계 기능 구현

반응형

이제 앱에 예측된 영양 정보를 기록하고, 통계로 확인할 수 있는 기능을 추가해보자. 이 기능은 사용자가 매일 어떤 영양소를 얼마나 섭취했는지 파악할 수 있게 도와줘! 📊🍽️


🗂️ 1단계: SharedPreferences 설정

pubspec.yaml에 이미 아래 항목이 있어야 해:

dependencies:
  shared_preferences: ^2.2.2

없다면 추가하고 flutter pub get 실행!


📦 2단계: 기록 저장/불러오기 함수 작성

lib/services/record_service.dart

import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

class RecordService {
  static const String key = 'meal_records';

  static Future<void> saveRecord(Map<String, dynamic> data) async {
    final prefs = await SharedPreferences.getInstance();
    final List<String> current = prefs.getStringList(key) ?? [];
    current.add(jsonEncode(data));
    await prefs.setStringList(key, current);
  }

  static Future<List<Map<String, dynamic>>> loadRecords() async {
    final prefs = await SharedPreferences.getInstance();
    final raw = prefs.getStringList(key) ?? [];
    return raw.map((e) => jsonDecode(e)).cast<Map<String, dynamic>>().toList();
  }
}

💾 3단계: 영양 정보 저장 기능 추가

home_screen.dart에 저장 버튼 추가:

import '../services/record_service.dart';

ElevatedButton(
  onPressed: () {
    if (_foodName != null && _nutrition != null) {
      RecordService.saveRecord({
        'name': _foodName,
        'nutrition': _nutrition,
        'timestamp': DateTime.now().toIso8601String()
      });
    }
  },
  child: const Text('식사 기록 저장'),
),

📊 4단계: 통계화면 UI 구현

lib/screens/stat_screen.dart

import 'package:flutter/material.dart';
import '../services/record_service.dart';

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

  @override
  State<StatScreen> createState() => _StatScreenState();
}

class _StatScreenState extends State<StatScreen> {
  double totalCal = 0;
  double totalCarb = 0;
  double totalProtein = 0;
  double totalFat = 0;

  @override
  void initState() {
    super.initState();
    _loadStats();
  }

  void _loadStats() async {
    final records = await RecordService.loadRecords();
    for (final r in records) {
      final n = r['nutrition'];
      totalCal += (n['nf_calories'] ?? 0).toDouble();
      totalCarb += (n['nf_total_carbohydrate'] ?? 0).toDouble();
      totalProtein += (n['nf_protein'] ?? 0).toDouble();
      totalFat += (n['nf_total_fat'] ?? 0).toDouble();
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('오늘의 섭취 통계')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('총 칼로리: ${totalCal.toStringAsFixed(1)} kcal'),
            Text('총 탄수화물: ${totalCarb.toStringAsFixed(1)} g'),
            Text('총 단백질: ${totalProtein.toStringAsFixed(1)} g'),
            Text('총 지방: ${totalFat.toStringAsFixed(1)} g'),
          ],
        ),
      ),
    );
  }
}

홈 화면에서 이동 버튼도 하나 추가해줘:

ElevatedButton(
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const StatScreen()),
    );
  },
  child: const Text('섭취 통계 보기'),
)

✅ 결과 요약

  • 사용자는 음식 인식 → 영양 정보 확인 → 기록 저장 → 통계 확인의 흐름 완성!
  • 일/주간 단위 통계로 확장 가능성도 확보

다음 에피소드 예고

00026. [APP-00003] AI 음식 영양 분석 앱 개발기 #7 – 앱 완성 및 배포 준비

  • 앱 아이콘/스플래시 설정
  • 깃허브 공유용 정리 및 블로그 마무리
반응형