In this Flutter tutorial, we will learn how to create a pomodoro timer app using Flutter. The pomodoro technique is a time management method that helps improve productivity by breaking work into intervals. With Flutter, we can easily build a pomodoro timer app that allows users to set work and break durations, track their progress, and stay focused on their tasks. Let's get started and dive into the world of Flutter app development!

Building a Pomodoro Timer app in Flutter involves creating a simple timer with intervals for work and break periods. Below is a step-by-step tutorial with code snippets to help you get started.

Step 1: Set Up a Flutter Project

Make sure you have Flutter installed. If not, follow the official installation guide.

Create a new Flutter project using the following command:

flutter create pomodoro_timer

Navigate to the project directory:

cd pomodoro_timer

Step 2: Add Dependencies

Open your pubspec.yaml file and add the following dependencies for the timer and sound:

dependencies:
  flutter:
    sdk: flutter
  percent_indicator: ^3.0.1
  audioplayers: ^0.20.1

Run flutter pub get to install the dependencies.

Step 3: Design the User Interface

Replace the contents of lib/main.dart with the following code:

import 'package:flutter/material.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:audioplayers/audioplayers.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pomodoro Timer',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PomodoroTimer(),
    );
  }
}

class PomodoroTimer extends StatefulWidget {
  @override
  _PomodoroTimerState createState() => _PomodoroTimerState();
}

class _PomodoroTimerState extends State<PomodoroTimer> {
  bool isRunning = false;
  int workDuration = 25 * 60; // 25 minutes
  int breakDuration = 5 * 60; // 5 minutes
  int currentDuration = 25 * 60; // Initial duration

  final AudioPlayer audioPlayer = AudioPlayer();
  final String soundPath = 'assets/bell.mp3';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pomodoro Timer'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CircularPercentIndicator(
              radius: 200.0,
              lineWidth: 10.0,
              percent: 1 - (currentDuration / workDuration),
              center: Text(
                formatDuration(currentDuration),
                style: TextStyle(fontSize: 24.0),
              ),
              progressColor: Colors.blue,
            ),
            SizedBox(height: 20.0),
            ElevatedButton(
              onPressed: () {
                if (isRunning) {
                  resetTimer();
                } else {
                  startTimer();
                }
              },
              child: Text(isRunning ? 'Reset' : 'Start'),
            ),
          ],
        ),
      ),
    );
  }

  void startTimer() {
    setState(() {
      isRunning = true;
    });

    const oneSec = const Duration(seconds: 1);
    Timer.periodic(
      oneSec,
      (Timer timer) {
        if (currentDuration < 1) {
          playSound();
          if (isWorkTime()) {
            currentDuration = breakDuration;
          } else {
            currentDuration = workDuration;
          }
          timer.cancel();
          startTimer();
        } else {
          setState(() {
            currentDuration -= 1;
          });
        }
      },
    );
  }

  void resetTimer() {
    setState(() {
      isRunning = false;
      currentDuration = workDuration;
    });
  }

  bool isWorkTime() {
    return currentDuration == breakDuration;
  }

  String formatDuration(int durationInSeconds) {
    int minutes = durationInSeconds ~/ 60;
    int seconds = durationInSeconds % 60;
    return '$minutes:${seconds.toString().padLeft(2, '0')}';
  }

  Future<void> playSound() async {
    int result = await audioPlayer.play(soundPath, isLocal: true);
    if (result == 1) {
      // success
    } else {
      // failure
    }
  }
}

Step 4: Add Sound

Download a bell sound in MP3 format and place it in the assets folder of your project. Update the pubspec.yaml file to include the sound file:

flutter:
  assets:
    - assets/bell.mp3

Step 5: Run the App

Run your Flutter app using the following command:

flutter run

Now, you should have a simple Pomodoro Timer app that displays a circular progress indicator and allows you to start/reset the timer. The app will play a bell sound when the timer reaches zero.

Feel free to customize the app further according to your preferences and requirements.