[flutter] 플러터 Stepper를 사용하여 사용자가 선택한 칼로리 수를 입력하는 음식 트래커 애플리케이션을 만들어보자.

이번 예제에서는 플러터의 Stepper 위젯을 사용하여 사용자가 선택한 칼로리 수를 입력하는 음식 트래커 애플리케이션을 만들어보겠습니다. Stepper 위젯은 여러 단계로 구성된 입력 화면을 만들기에 적합한 위젯입니다.

Step 1: 프로젝트 설정

먼저, flutter create 명령어를 사용하여 새로운 플러터 프로젝트를 생성합니다. 그리고 다음과 같은 의존성을 pubspec.yaml 파일에 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2

의존성을 추가한 뒤 flutter packages get 명령어를 실행하여 패키지를 설치합니다.

Step 2: 애플리케이션 UI 구성

이제 main.dart 파일을 열고 다음과 같이 애플리케이션 UI를 구성합니다.

import 'package:flutter/material.dart';

void main() {
  runApp(FoodTrackerApp());
}

class FoodTrackerApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Food Tracker',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FoodTrackerPage(),
    );
  }
}

class FoodTrackerPage extends StatefulWidget {
  @override
  _FoodTrackerPageState createState() => _FoodTrackerPageState();
}

class _FoodTrackerPageState extends State<FoodTrackerPage> {
  int _currentStep = 0;
  int _selectedCalories = 0;

  List<Step> _steps = [
    Step(
      title: Text('1단계'),
      content: Text('음식의 칼로리 수를 선택하세요.'),
      isActive: true,
    ),
    Step(
      title: Text('2단계'),
      content: Text('선택한 칼로리 수를 확인하세요.'),
      isActive: false,
    ),
    Step(
      title: Text('3단계'),
      content: Text('완료되었습니다.'),
      isActive: false,
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Food Tracker'),
      ),
      body: Stepper(
        currentStep: _currentStep,
        onStepContinue: () {
          if (_currentStep < _steps.length - 1) {
            setState(() {
              _currentStep++;
            });
          }
        },
        onStepCancel: () {
          if (_currentStep > 0) {
            setState(() {
              _currentStep--;
            });
          }
        },
        steps: _steps,
        controlsBuilder: (BuildContext context,
            {VoidCallback? onStepContinue, VoidCallback? onStepCancel}) {
          return Row(
            children: [
              ElevatedButton(
                onPressed: onStepCancel,
                child: Text('이전'),
              ),
              SizedBox(width: 10),
              ElevatedButton(
                onPressed: onStepContinue,
                child: Text('다음'),
              ),
            ],
          );
        },
        onStepTapped: (int step) {
          if (step <= _currentStep) {
            setState(() {
              _currentStep = step;
            });
          }
        },
      ),
    );
  }
}

위의 코드는 FoodTrackerPage 위젯을 생성하고 Stepper를 사용하여 애플리케이션의 단계를 구성합니다. Stepper에는 각 단계를 나타내는 Step 위젯들을 전달하고, 사용자가 이전/다음 버튼을 클릭하거나 직접 단계를 선택할 수 있도록 합니다. 또한 _currentStep 변수를 사용하여 현재 표시되는 단계를 추적하고, onStepContinueonStepCancel 콜백 함수를 사용하여 이전/다음 버튼을 처리합니다.

애플리케이션을 실행하면 현재 단계에 따라 다른 내용을 표시하는 Stepper 위젯을 확인할 수 있습니다.

Step 3: 칼로리 선택 기능 구현

다음으로, 사용자가 각 단계에서 칼로리 수를 선택할 수 있도록 기능을 구현해보겠습니다.

class _FoodTrackerPageState extends State<FoodTrackerPage> {
  // ...

  Widget _buildStepContent(int step) {
    switch (step) {
      case 0:
        return _buildCalorieSelectionStep();
      case 1:
        return _buildCalorieConfirmationStep();
      case 2:
        return _buildCompletionStep();
      default:
        return SizedBox.shrink();
    }
  }

  Widget _buildCalorieSelectionStep() {
    return Column(
      children: [
        Text('오늘 섭취한 음식의 칼로리 수를 선택해주세요.'),
        SizedBox(height: 10),
        Container(
          width: 200,
          child: Slider(
            min: 0,
            max: 1000,
            divisions: 10,
            value: _selectedCalories.toDouble(),
            onChanged: (value) {
              setState(() {
                _selectedCalories = value.toInt();
              });
            },
          ),
        ),
        SizedBox(height: 10),
        Text('$_selectedCalories 칼로리'),
      ],
    );
  }

  Widget _buildCalorieConfirmationStep() {
    return Column(
      children: [
        Text('선택한 칼로리 수는 $_selectedCalories입니다.'),
        SizedBox(height: 10),
        ElevatedButton(
          onPressed: () {
            setState(() {
              _currentStep++;
            });
          },
          child: Text('다음'),
        ),
      ],
    );
  }

  Widget _buildCompletionStep() {
    return Column(
      children: [
        Text('음식 트래커가 완료되었습니다!'),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Food Tracker'),
      ),
      body: Stepper(
        // ...
        content: _buildStepContent(_currentStep),
        // ...
      ),
    );
  }
}

위의 코드는 _buildStepContent 함수를 추가하여 선택한 단계에 따라 다른 내용을 반환합니다. _buildCalorieSelectionStep 함수에서는 Slider를 사용하여 칼로리를 선택할 수 있도록 하고, 선택한 칼로리 수를 표시합니다. _buildCalorieConfirmationStep 함수에서는 선택한 칼로리 수를 확인하고 다음 단계로 이동할 수 있는 버튼을 추가합니다. _buildCompletionStep 함수에서는 트래커 완료 메시지를 표시합니다.

애플리케이션을 실행하고 단계를 완료하면 다음 단계로 이동하거나 트래커가 완료된 메시지를 확인할 수 있습니다.

이제 플러터의 Stepper를 사용하여 사용자가 선택한 칼로리 수를 입력하는 음식 트래커 애플리케이션을 구현하는 방법을 알게 되었습니다. 추가로 디자인을 개선하거나 저장 기능을 추가할 수도 있습니다.