Home > Back-end >  How can I maintain the height of an animation widget even if it's contained in another widget?
How can I maintain the height of an animation widget even if it's contained in another widget?

Time:01-03

This is what I mean:

enter image description here

As you can see the animation starts from the top to bottom, the problem begins when I integrate another file into it

Example: enter image description here

Here, I wrapped with another widget and don't respect the height of the app bar

This is my code:

home_page_timer.dart

import 'dart:core';
import 'package:flutter/material.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'package:pomodoro/5.hourglass_animation/countdown_timer/pomodoro_animation.dart';
import 'dart:async';

class HomePageTimerUI extends StatefulWidget {
  const HomePageTimerUI({Key? key}) : super(key: key);

  @override
  State<HomePageTimerUI> createState() => _HomePageTimerUIState();
}

class _HomePageTimerUIState extends State<HomePageTimerUI>
    with TickerProviderStateMixin {
  late TabController _tabController;

  late Timer timer;
  late AnimationController controller;

  String get countText {
    Duration count = controller.duration! * controller.value;
    return controller.isDismissed
        ? '${controller.duration!.inHours.toString().padLeft(2, '0')}:${(controller.duration!.inMinutes % 60).toString().padLeft(2, '0')}:${(controller.duration!.inSeconds % 60).toString().padLeft(2, '0')}'
        : '${count.inHours.toString().padLeft(2, '0')}:${(count.inMinutes % 60).toString().padLeft(2, '0')}:${(count.inSeconds % 60).toString().padLeft(2, '0')}';
  }

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  void notify() {
    if (countText == '00:00:00') {
      _tabController.animateTo(1, duration: const Duration(milliseconds: 300));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: MediaQuery.of(context).size.height,
      child: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            elevation: 0,
            backgroundColor: Colors.transparent,
            bottom: PreferredSize(
              preferredSize: const Size.fromHeight(35),
              child: Container(
                color: Colors.transparent,
                child: SafeArea(
                  child: Column(
                    children: <Widget>[
                      TabBar(
                          controller: _tabController,
                          indicator: const UnderlineTabIndicator(
                              borderSide: BorderSide(
                                  color: Color(0xff3B3B3B), width: 4.0),
                              insets:
                                  EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 11.0)),
                          indicatorWeight: 15,
                          indicatorSize: TabBarIndicatorSize.label,
                          labelColor: const Color(0xff3B3B3B),
                          labelStyle: const TextStyle(
                              fontSize: 12,
                              letterSpacing: 1.3,
                              fontWeight: FontWeight.w500),
                          unselectedLabelColor: const Color(0xffD7D7D7),
                          tabs: const [
                             Tab(
                              text: "POMODORO",
                              icon: Icon(Icons.work_history, size: 35),
                            ),
                             Tab(
                              text: "SHORT BREAK",
                              icon: Icon(Icons.ramen_dining, size: 35),
                            ),
                             Tab(
                              text: "LONG BREAK",
                              icon: Icon(Icons.battery_charging_full_rounded,
                                  size: 35),
                            ),
                          ])
                    ],
                  ),
                ),
              ),
            ),
          ),
          body: TabBarView(
            controller: _tabController,
            children: <Widget>[
              Center(
                child: Container(
                  height: MediaQuery.of(context).size.height,
                  child: StartPomodoro(end: DateTime.now())),
              ),
              const Center(
                child: Text('short break'),
              ),
              const Center(
                child: Text('long break '),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

start_pomodoro.dart

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pomodoro/5.hourglass_animation/countdown_timer/responsive.dart';

class StartPomodoro extends StatefulWidget {
  const StartPomodoro({super.key, required this.end});

  final DateTime end;

  @override
  State<StartPomodoro> createState() => _StartPomodoroState();
}

class _StartPomodoroState extends State<StartPomodoro>
    with TickerProviderStateMixin {
  final now = DateTime.now();

  List<bool> isSelected = [true, false];
  late Timer timer;
  late AnimationController controller;

  String get countText {
    Duration count = controller.duration! * controller.value;
    return controller.isDismissed
        ? '${controller.duration!.inHours.toString().padLeft(2, '0')}:${(controller.duration!.inMinutes % 60).toString().padLeft(2, '0')}:${(controller.duration!.inSeconds % 60).toString().padLeft(2, '0')}'
        : '${count.inHours.toString().padLeft(2, '0')}:${(count.inMinutes % 60).toString().padLeft(2, '0')}:${(count.inSeconds % 60).toString().padLeft(2, '0')}';
  }

  double progress = 1.0;
  bool LongBreak = true;

  void notify() {
    if (countText == '00:00:00') {}
  }

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 0),
    );
    controller.addListener(() {
      notify();
      if (controller.isAnimating) {
        setState(() {
          progress = controller.value;
        });
      } else {
        setState(() {
          progress = 1.0;
          LongBreak = true;
        });
      }
    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor:
            LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
        body: Stack(
          children: [
            GestureDetector(
              onTap: () {
                if (controller.isDismissed) {
                  showModalBottomSheet(
                    context: context,
                    builder: (context) => SizedBox(
                      height: 300,
                      child: CupertinoTimerPicker(
                        initialTimerDuration: controller.duration!,
                        onTimerDurationChanged: (time) {
                          setState(() {
                            controller.duration = time;
                          });
                        },
                      ),
                    ),
                  );
                }
              },
              child: AnimatedBuilder(
                  animation: controller,
                  builder: (context, child) {
                    return Stack(
                      children: <Widget>[
                        Align(
                          alignment: Alignment.bottomCenter,
                          child: Container(
                            color: const Color(0xffD94530),
                            height: controller.value *
                                MediaQuery.of(context).size.height,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Responsive(
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              crossAxisAlignment: CrossAxisAlignment.center,
                              children: <Widget>[
                                Align(
                                  alignment: Alignment.bottomCenter,
                                  child: Align(
                                    alignment: FractionalOffset.bottomCenter,
                                    child: Container(
                                      width:
                                          MediaQuery.of(context).size.width,
                                      height: 210,
                                      decoration: const BoxDecoration(
                                        color: Color.fromARGB(
                                            255, 245, 245, 245),
                                      ),
                                      child: Container(
                                        padding: const EdgeInsets.all(20.0),
                                        child: Column(
                                          crossAxisAlignment:
                                              CrossAxisAlignment.start,
                                          children: [
                                            const Text(
                                              "Hyper-focused on... ( add task)",
                                              style: TextStyle(
                                                fontSize: 22.0,
                                                fontWeight: FontWeight.w500,
                                              ),
                                            ),
                                            const SizedBox(height: 16),
                                            Center(
                                              child: Column(
                                                mainAxisAlignment:
                                                    MainAxisAlignment.center,
                                                children: [
                                                  Row(
                                                    mainAxisAlignment:
                                                        MainAxisAlignment
                                                            .center,
                                                                                                                  crossAxisAlignment: CrossAxisAlignment.center,
      
                                                    children: [
                                                      Center(
                                                        child: Text(
                                                          countText,
                                                          style:
                                                              const TextStyle(
                                                            fontWeight:
                                                                FontWeight.w600,
                                                            letterSpacing: 4,
                                                            fontSize: 65.0,
                                                            color: Color(
                                                                0xff3B3B3B),
                                                          ),
                                                        ),
                                                      ),
                                                    ],
                                                  ),
                                                  Row(
                                                    mainAxisAlignment:
                                                        MainAxisAlignment
                                                            .center,
                                                            crossAxisAlignment: CrossAxisAlignment.center,
                                                    children: const [
                                                      Center(
                                                        child: Text(
                                                          '      Hours      Minutes      Seconds      ',
                                                          style: TextStyle(
                                                            fontWeight:
                                                                FontWeight.w500,
                                                            letterSpacing: 2,
                                                            fontSize: 20.0,
                                                            color: Color(
                                                                0xff3B3B3B),
                                                          ),
                                                        ),
                                                      ),
                                                    ],
                                                  ),
                                                ],
                                              ),
                                            ),
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                ),
                                //Spacer(),
                                Responsive(
                                  child: Column(
                                    mainAxisAlignment:
                                        MainAxisAlignment.center,
                                    crossAxisAlignment:
                                        CrossAxisAlignment.stretch,
                                    children: [
                                      AnimatedBuilder(
                                          animation: controller,
                                          builder: (context, child) {
                                            return const Padding(
                                              padding: EdgeInsets.symmetric(
                                                  vertical: 2.0,
                                                  horizontal: 15.0),
                                            );
                                          }),
                                      AnimatedBuilder(
                                          animation: controller,
                                          builder: (context, child) {
                                            return Padding(
                                              padding:
                                                  const EdgeInsets.symmetric(
                                                      vertical: 2.0,
                                                      horizontal: 15.0),
                                              child: FloatingActionButton
                                                  .extended(
                                                      backgroundColor:
                                                          const Color(
                                                              0xffFAFAFA),
                                                      onPressed: () {
                                                        if (controller
                                                            .isAnimating) {
                                                          controller.stop();
                                                          setState(() {
                                                            LongBreak = false;
                                                          });
                                                        } else {
                                                          controller.reverse(
                                                              from: controller
                                                                          .value ==
                                                                      0
                                                                  ? 1.0
                                                                  : controller
                                                                      .value);
                                                          setState(() {
                                                            LongBreak = false;
                                                          });
                                                        }
                                                      },
                                                      icon: Icon(
                                                        controller.isAnimating
                                                            ? Icons.pause
                                                            : Icons
                                                                .play_arrow,
                                                        color: const Color(
                                                            0xff3B3B3B),
                                                      ),
                                                      label: Text(
                                                        controller.isAnimating
                                                            ? "Pause"
                                                            : "Start",
                                                        style: const TextStyle(
                                                            color: Color(
                                                                0xff3B3B3B)),
                                                      )),
                                            );
                                          }),
                                    ],
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    );
                  }),
            ),
          ],
        ),
      ),
    );
  }

  AnimationController _buildClockAnimation(TickerProvider tickerProvider) {
    return AnimationController(
      vsync: tickerProvider,
      duration: const Duration(milliseconds: 750),
    );
  }

  void _animateLeftDigit(
    int prev,
    int current,
    AnimationController controller,
  ) {
    final prevFirstDigit = (prev / 10).floor();
    final currentFirstDigit = (current / 10).floor();
    if (prevFirstDigit != currentFirstDigit) {
      controller.forward();
    }
  }
}

How can I provide a height from the animation widget which respects the app bar widget and there is no lag when I started the timer?

What I mean is that I want to start the animation here:

enter image description here

Thank you for any help you can offer

CodePudding user response:

As @Henrique Zanferrari suggested you are using height of the screen in

height: MediaQuery.of(context).size.height

Which is limiting the widgets to follow along with the appBar.

Try replacing this height with more general Widget like Expanded or Flexible like so.

  • Related