기술은 나의 도구

[노마드코더 플러터] Pomodoro

Flexible Class

  • Documentation
  • 하위 위젯이 남은 공간을 어떻게 분배할지를 결정
  • 하위 위젯에게 유연성을 제공하는 것이 목적
  • fit: Flexfit.tight 를 설정하면 Expanded 와 동일한 동작

Expanded Class

  • Documentation
  • Row, Column 또는 Flex 의 하위 위젯의 사용가능한 공간을 확장한다.
  • 하위 위젯의 할당된 공간을 채우기 위한 목적

main.dart

import 'package:flutter/material.dart';
import 'package:nc_flutter_pomodoro/screens/home_screen.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSwatch(
          backgroundColor: const Color(0xFFE7626C),
        ),
        textTheme: const TextTheme(
          displayLarge: TextStyle(
            color: Color(0xFF232B55),
          ),
        ),
        cardColor: const Color(0xFFF4EDDB),
      ),
      home: const HomeScreen(),
    );
  }
}

home_screen.dart

import 'dart:async';
import 'package:flutter/material.dart';

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

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  static const originSeconds = 5;
  int totalSeconds = originSeconds;
  bool isRunning = false;
  int totalPomodoros = 0;
  late Timer timer;

  void onTick(Timer timer) {
    setState(() {
      if (totalSeconds == 0) {
        timer.cancel();
        isRunning = false;
        totalPomodoros = totalPomodoros + 1;
        totalSeconds = originSeconds;
      } else {
        totalSeconds = totalSeconds - 1;
      }
    });
  }

  void onStartPressed() {
    timer = Timer.periodic(
      const Duration(seconds: 1),
      onTick,
    );
    setState(() {
      isRunning = true;
    });
  }

  void onPausePressed() {
    timer.cancel();
    setState(() {
      isRunning = false;
    });
  }

  String twoDigits(int n) => n.toString().padLeft(2, '0');

  String format(int seconds) {
    var duration = Duration(seconds: seconds);
    var digitMinutes = twoDigits(duration.inMinutes.remainder(60));
    var digitSeconds = twoDigits(duration.inSeconds.remainder(60));
    return "$digitMinutes:$digitSeconds";
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Theme.of(context).colorScheme.background,
      body: Column(
        children: [
          Flexible(
            flex: 1,
            child: Container(
              alignment: Alignment.bottomCenter,
              child: Text(
                format(totalSeconds), //'25:00',
                style: TextStyle(
                  fontSize: 89,
                  fontWeight: FontWeight.w600,
                  color: Theme.of(context).cardColor,
                ),
              ),
            ),
          ),
          Flexible(
            flex: 2,
            child: Center(
              child: IconButton(
                iconSize: 120,
                color: Theme.of(context).cardColor,
                icon: isRunning
                    ? const Icon(
                        Icons.pause_circle_outline,
                      )
                    : const Icon(
                        Icons.play_circle_outline,
                      ),
                onPressed: isRunning ? onPausePressed : onStartPressed,
              ),
            ),
          ),
          Flexible(
            flex: 1,
            child: Row(
              children: [
                Expanded(
                  child: Container(
                    decoration: BoxDecoration(
                      color: Theme.of(context).cardColor,
                      borderRadius: BorderRadius.circular(50),
                    ),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          'Pomodoros',
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.w600,
                            color:
                                Theme.of(context).textTheme.displayLarge!.color,
                          ),
                        ),
                        Text(
                          '$totalPomodoros',
                          style: TextStyle(
                            fontSize: 58,
                            fontWeight: FontWeight.w600,
                            color:
                                Theme.of(context).textTheme.displayLarge!.color,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

결과물

nc.flutter.pomodoro

  • #노마드코더
  • #플러터