I got this error in debug console:
Launching lib\main.dart on Chrome in debug mode...
lib\main.dart:1
Error: Expected an identifier, but got ')'.
lib/apilar_codigo/stacked_all.dart:20
Try inserting an identifier before ')'.
StartPomodoro(end: ),
Failed to compile application.
Exited (sigterm)
How can I solved it?
This is my code:
startPomodoro.dart
class StartPomodoro extends StatefulWidget {
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: SizedBox(
height: 460,
child: Stack(
children: [
Positioned(
top: 220,
left: 16,
child: GestureDetector(
onTap: () {
if (controller.isDismissed) {
showModalBottomSheet(
context: context,
builder: (context) => Container(
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: Column(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
child: Align(
alignment: Alignment.center,
child: Align(
alignment: FractionalOffset.center,
child: Container(
width: MediaQuery.of(context)
.size
.width -
64,
height: 210,
decoration: const BoxDecoration(
color: Color.fromARGB(
255, 245, 245, 245),
boxShadow: [
BoxShadow(
color: Color(0x22000000),
blurRadius: 64,
blurStyle: BlurStyle.outer,
offset: Offset(0, 16),
),
],
),
child: Container(
padding: const EdgeInsets.all(24.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const Text(
"Hyper focused on...",
style: TextStyle(
fontSize: 22.0,
fontWeight:
FontWeight.w600,
),
),
const SizedBox(height: 16),
Center(
child: Column(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Text(
countText,
style:
const TextStyle(
letterSpacing:
4,
fontSize: 65.0,
color: Color(
0xff3B3B3B),
),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: const [
Text(
' Hours Minutes Seconds ',
style: TextStyle(
letterSpacing:
2,
fontSize: 20.0,
color: Color(
0xff3B3B3B),
),
),
],
),
],
),
),
],
),
),
),
),
),
),
),
],
),
),
],
);
}),
),
),
Expanded(
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();
}
}
}
StackPages.dart
class StackPages extends StatelessWidget {
const StackPages({super.key});
#override
Widget build(BuildContext context) {
return Stack(
// ignore: prefer_const_literals_to_create_immutables
children: [
// ChartBar()
// PieChartSample1(),
// ToDoPage(),
StartPomodoro(end: ),
// HomePageTimerUI(),
],
);
}
}
How to get rid of this problem? I tried this but no luck:
StartPomodoro(end: end),
Thank you for any help you can offer
Parameter end is of type DateTime.
To get over this error provide value of type DateTime in end parameter.
Try following code:
StartPomodoro(end: DateTime.now().add(const Duration(days: 1)))
: Error: Expected an identifier, but got ':'.
../…/painting/_network_image_io.dart:147
Try inserting an identifier before ':'.
:rethrow;
^
: Error: Expected ';' after this.
../…/painting/_network_image_io.dart:146
});
^
: Error: Unexpected token ':'.
../…/painting/_network_image_io.dart:147
:rethrow;
getting this error in my code i haven't created anything yet but still showing this error it has to show the basic hello world counter interface,but its not showing that also ,what's the problem I am getting I don't know previously I creating a project but while I was in the middle of that project the same issue had occure after that project everytime if I creating a new project also it showing the same error.
Related
This is what I mean:
As you can see the animation starts from the top to bottom, the problem begins when I integrate another file into it
Example:
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:
Thank you for any help you can offer
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.
I got these errors in debug console:
Another exception was thrown: _RenderInkFeatures object was given an infinite size during layout.
Another exception was thrown: RenderPhysicalModel object was given an infinite size during layout.
Another exception was thrown: RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
Another exception was thrown: _RenderInkFeatures object was given an infinite size during layout.
Another exception was thrown: RenderPhysicalModel object was given an infinite size during layout.
Another exception was thrown: _RenderSingleChildViewport object was given an infinite size during layout.
Another exception was thrown: RenderIgnorePointer object was given an infinite size during layout.
Another exception was thrown: RenderSemanticsAnnotations object was given an infinite size during layout.
Another exception was thrown: RenderPointerListener object was given an infinite size during layout.
Another exception was thrown: RenderSemanticsGestureHandler object was given an infinite size during layout.
Another exception was thrown: RenderPointerListener object was given an infinite size during layout.
Another exception was thrown: _RenderScrollSemantics object was given an infinite size during layout.
Another exception was thrown: RenderRepaintBoundary object was given an infinite size during layout.
Another exception was thrown: RenderCustomPaint object was given an infinite size during layout.
Another exception was thrown: RenderMouseRegion object was given an infinite size during layout.
Another exception was thrown: RenderPointerListener object was given an infinite size during layout.
Another exception was thrown: RenderSemanticsGestureHandler object was given an infinite size during layout.
Another exception was thrown: RenderRepaintBoundary object was given an infinite size during layout.
Another exception was thrown: RenderPadding object was given an infinite size during layout.
Another exception was thrown: A RenderFlex overflowed by Infinity pixels on the bottom.
Another exception was thrown: A RenderFlex overflowed by 32 pixels on the bottom.
This is what I got:
[]
I was trying to achieve this design:
This is my code:
homepage.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 SafeArea(
child: Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(55),
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(55),
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: 40),
),
Tab(
text: "SHORT BREAK",
icon: Icon(Icons.ramen_dining, size: 40),
),
Tab(
text: "LONG BREAK",
icon: Icon(Icons.battery_charging_full_rounded,
size: 40),
),
])
],
),
),
),
),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
Center(
child: StartPomodoro(end: DateTime.now()),
),
const Center(
child: Text('short break'),
),
const Center(
child: Text('long break '),
),
],
),
),
),
),
body: Column(children: [
SizedBox(height: 10,),
StartPomodoro(end: DateTime.now())
]),
),
);
}
}
startpomodoro.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: SingleChildScrollView(
child: Scaffold(
backgroundColor:
LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
body: GestureDetector(
onTap: () {
if (controller.isDismissed) {
showModalBottomSheet(
context: context,
builder: (context) => Container(
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: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
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),
),
),
),
],
),
],
),
),
],
),
),
),
),
),
SizedBox(height: 150,),
//Spacer(),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
AnimatedBuilder(
animation: controller,
builder: (context, child) {
return const Padding(
padding: EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 0.0),
);
}),
AnimatedBuilder(
animation: controller,
builder: (context, child) {
return Padding(
padding:
const EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 0.0),
child:
Container(
color: const Color(0xffFAFAFA),
width: MediaQuery.of(context).size.width,
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();
}
}
}
I tried to wrap the scaffold widget to SinglChildScrollView to solve the error but no luck, How can I achieve the second screenshot?
Thank you for any help you can offer
For now I have this
I want to achieve this desing
This is my code:
HomePageTimerUI .dart
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: 600,
width: double.infinity,
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
bottom: PreferredSize(
preferredSize: Size.fromHeight(55),
child: Container(
color: Colors.transparent,
child: SafeArea(
child: Column(
children: <Widget>[
TabBar(
controller: _tabController,
indicator: 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: Color(0xff3B3B3B),
labelStyle: TextStyle(
fontSize: 12,
letterSpacing: 1.3,
fontWeight: FontWeight.w500),
unselectedLabelColor: Color(0xffD7D7D7),
tabs: [
Tab(
text: "POMODORO",
icon: Icon(Icons.work_history, size: 40),
),
Tab(
text: "SHORT BREAK",
icon: Icon(Icons.ramen_dining, size: 40),
),
Tab(
text: "LONG BREAK",
icon: Icon(
Icons.battery_charging_full_rounded,
size: 40),
),
])
],
),
),
),
),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
Center(
child: StartPomodoro(),
),
// Center(
// child: ShortBreak(),
// ),
// Center(child: LongBreak()),
],
),
bottomNavigationBar: Container(
height: 110,
color: Color(0xffFAFAFA),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15.0, vertical: 20),
child: GNav(
iconSize: 40,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
backgroundColor: Color(0xffFAFAFA),
color: Color(0xffD7D7D7),
activeColor: Color(0xff3B3B3B),
tabBackgroundColor: Color(0xffF0F0F0),
gap: 8,
onTabChange: (index) {
print(index);
},
padding: EdgeInsets.all(15),
tabs: [
GButton(
icon: Icons.settings,
text: 'Settings',
),
GButton(
icon: Icons.person,
text: "Profile",
),
GButton(
icon: Icons.task,
text: "Tasks",
),
GButton(
icon: Icons.show_chart,
text: "Performance",
),
],
),
),
),
)));
}
}
startpomodoro.dart
class StartPomodoro extends StatefulWidget {
const StartPomodoro({Key? key}) : super(key: key);
#override
State<StartPomodoro> createState() => _StartPomodoroState();
}
class _StartPomodoroState extends State<StartPomodoro>
with TickerProviderStateMixin {
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) {
ThemeData themeData = Theme.of(context);
return Scaffold(
backgroundColor:
LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
body: GestureDetector(
onTap: () {
if (controller.isDismissed) {
showModalBottomSheet(
context: context,
builder: (context) => Container(
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 *
0.640,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Align(
alignment: FractionalOffset.bottomCenter,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment:
MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.center,
children: <Widget>[
Text(
countText,
style: const TextStyle(
fontSize: 90.0,
color: Color(0xffFAFAFA),
),
),
],
),
),
),
),
),
Expanded(
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)),
)),
);
}),
const SizedBox(width: 20, height: 100),
],
),
),
],
),
),
],
);
}),
),
);}
}
class CustomTimerPainter extends CustomPainter {
CustomTimerPainter({
required this.animation,
required this.backgroundColor,
required this.color,
}) : super(repaint: animation);
final Animation<double> animation;
final Color backgroundColor, color;
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = backgroundColor
..strokeWidth = 10.0
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke;
canvas.drawCircle(size.center(Offset.zero), size.width / 2.0, paint);
paint.color = color;
double progress = (1.0 - animation.value) * 2 * math.pi;
canvas.drawArc(Offset.zero & size, math.pi * 1.5, -progress, false, paint);
}
#override
bool shouldRepaint(CustomTimerPainter old) {
return animation.value != old.animation.value ||
color != old.color ||
backgroundColor != old.backgroundColor;
}
If I cut and paste the start widget to the HomePageTimerUI I cant do it well because the startpomodoro page has all the controllers to control the timer and animations, so how can I replace the start / pause button to the gnav widget maintaining its height and also initialize the timer?
Thank you for any help you can offer
It's difficult to precisely figure out from the code produced. Because of too many widgets and wrong indentations. I would give suggestions based on rough insights.
If you want to seperate two elements use Spacer that will do the job for you, Otherwise try the following approach.
Present approach (roughly)
Column
|_ Timer Container
|_ Floating button
to
Correct appraoch
Column
|_ Expanded
|_ Center
|_ Timer Container
|_ Floating Button
This is my design for now:
I want to achive this design:
As you can see, the container starts at the top and want I want to do is center it like the second screenshot.
This is my code:
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, });
//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) {
ThemeData themeData = Theme.of(context);
return SafeArea(
child: Scaffold(
backgroundColor:
LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
body: GestureDetector(
onTap: () {
if (controller.isDismissed) {
showModalBottomSheet(
context: context,
builder: (context) => Container(
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 *
0.722,
),
),
Spacer(),
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: Padding(
padding: const EdgeInsets.symmetric(
vertical: 2.0, horizontal: 15.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 210,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color:
const Color(0xffFAFAFA)
),
child: Container(
padding: const EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
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: SingleChildScrollView(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Text(
countText,
style: const TextStyle(
fontWeight:
FontWeight.w600,
letterSpacing: 4,
fontSize: 65.0,
color:
Color(0xff3B3B3B),
),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: const [
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 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)),
)),
);
}),
],
),
),
SizedBox(height: 10,),
],
),
),
),
],
);
}),
),
),
);
}
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();
}
}
}
For some reason, I'm unable to center the container, wrapped with the widget
center
and no luck, how can I center the timer container?
Thank you for any help you can offer
Its difficult to figure out the complete code because of lots of code and incorrect indentation. But as far as I can see, you are facing this problem because of using Spacer,
Spacer is pushing your floating button and the timer Container to its ends.
Try removing the Spacer and wrap the timer Container with Center and wrap it with Flexible this should solve your problem.
Your present code is roughly:
Column
|_ Timer Container
|_ Spacer
|_ Floating Button
Change it to:
Column
|_ Flexible
|_ Center
|_ Timer Container
|_ Floating Button
If you like to use Stack widget, use positional widget like Aling, Positioned on Stack. Based on your UI, using stack widget structure will be
return Stack(
children: <Widget>[
background(context),
Align(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: buildCounter(context),
),
),
Align(
alignment: Alignment.bottomCenter,
child: startPauseButtonBuild(),
),
],
);
Here is the full snippet, I've removed some part for minimal and padding widget to handle some space
void main() => runApp(MaterialApp(home: const StartPomodoro()));
class StartPomodoro extends StatefulWidget {
const StartPomodoro({
super.key,
});
#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) {
ThemeData themeData = Theme.of(context);
return SafeArea(
child: Scaffold(
backgroundColor:
LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
body: GestureDetector(
onTap: () {},
child: AnimatedBuilder(
animation: controller,
builder: (context, child) {
return Stack(
children: <Widget>[
background(context),
Align(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: buildCounter(context),
),
),
Align(
alignment: Alignment.bottomCenter,
child: startPauseButtonBuild(),
),
],
);
}),
),
),
);
}
Widget startPauseButtonBuild() {
return LayoutBuilder(
builder: (_, constraints) => Padding(
padding: const EdgeInsets.all(8.0),
child: AnimatedBuilder(
animation: controller,
builder: (context, child) {
return Padding(
padding:
const EdgeInsets.symmetric(vertical: 2.0, horizontal: 15.0),
child: SizedBox(
width: constraints.maxWidth,
child: FloatingActionButton.extended(
backgroundColor: const Color(0xffFAFAFA),
onPressed: () {},
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)),
),
),
),
);
}),
),
);
}
Column buildCounter(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: MediaQuery.of(context).size.width,
height: 210,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: const Color(0xffFAFAFA)),
child: Container(
padding: const EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
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: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
countText,
style: const TextStyle(
fontWeight: FontWeight.w600,
letterSpacing: 4,
fontSize: 65.0,
color: Color(0xff3B3B3B),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
' Hours Minutes Seconds ',
style: TextStyle(
fontWeight: FontWeight.w500,
letterSpacing: 2,
fontSize: 20.0,
color: Color(0xff3B3B3B),
),
),
],
),
],
),
),
),
],
),
),
),
),
),
],
);
}
Align background(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
color: const Color(0xffD94530),
height: controller.value * MediaQuery.of(context).size.height * 0.722,
),
);
}
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();
}
}
}
I am new to flutter animation, I have a stopwatch screen with a container that contains the stopwatch, a container with a list of laps, and 3 floating action buttons that do three things, reset, play-pause and lap. I want the stopwatch container to animate up when clicking on the lap button and then animate down when clicking on the reset button.
class _StopWatchScreenState extends State<StopWatchScreen>
with SingleTickerProviderStateMixin {
final StopWatchTimer _stopWatchTimer = StopWatchTimer();
final _isHours = true;
late AnimationController controller;
bool isPlaying = false;
bool lapClicked = false;
double value = 150.0;
final ScrollController scrollController = ScrollController();
#override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 200));
}
void dispose() {
super.dispose();
_stopWatchTimer.dispose();
scrollController.dispose();
controller.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
Center(
child: Padding(
padding: EdgeInsets.only(top: value), // Issue here
child: AnimatedContainer(
child: Center(
child: StreamBuilder<int>(
stream: _stopWatchTimer.rawTime,
initialData: _stopWatchTimer.rawTime.value,
builder: (context, snapshot) {
final value = snapshot.data;
final displayTime = StopWatchTimer.getDisplayTime(
value!,
hours: _isHours);
return Text(
displayTime,
style: GoogleFonts.lato(
fontSize: 40.0, color: Colors.white),
);
})),
width: 350.0,
height: 450.0,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 5.0),
shape: BoxShape.circle),
duration: const Duration(milliseconds: 100),
curve: Curves.fastLinearToSlowEaseIn,
),
),
),
Visibility(
visible: lapClicked,
child: Container(
height: 280.0,
child: StreamBuilder<List<StopWatchRecord>>(
stream: _stopWatchTimer.records,
initialData: _stopWatchTimer.records.value,
builder: (context, snapshot) {
final value = snapshot.data;
if (value!.isEmpty) {
return Container();
}
Future.delayed(const Duration(milliseconds: 100), () {
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 200),
curve: Curves.easeOut);
});
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: value.length,
itemBuilder: (context, index) {
final data = value[index];
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Text(
'Lap ${index + 1}',
style: GoogleFonts.lato(
fontSize: 30.0, color: Colors.white70),
),
),
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: Text('${data.displayTime}',
style: GoogleFonts.lato(
fontSize: 30.0,
color: Colors.white70)),
)
],
),
const Padding(
padding: EdgeInsets.only(top: 5.0),
child: Opacity(
opacity: 0.1,
child: Divider(
thickness: 1.5,
color: Colors.white70,
),
),
)
],
);
},
controller: scrollController,
);
},
),
),
),
],
),
floatingActionButton: Padding(
padding: const EdgeInsets.only(left: 30.0, bottom: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FloatingActionButton(
onPressed: () {
setState(() {
lapClicked = false;
value = 190.0;
});
controller.reverse();
_stopWatchTimer.onExecute.add(StopWatchExecute.reset);
},
child: const Icon(
Icons.refresh,
size: 30.0,
),
),
FloatingActionButton(
onPressed: () {
toggleIcon();
if (isPlaying == true) {
_stopWatchTimer.onExecute.add(StopWatchExecute.start);
} else {
_stopWatchTimer.onExecute.add(StopWatchExecute.stop);
}
},
child: AnimatedIcon(
icon: AnimatedIcons.play_pause,
size: 35.0,
progress: controller,
),
),
FloatingActionButton(
onPressed: () {
setState(() {
lapClicked = true;
value = 10.0;
});
_stopWatchTimer.onExecute.add(StopWatchExecute.lap);
},
child: const Icon(
Icons.timer,
size: 30.0,
),
),
],
),
),
),
);
}
void toggleIcon() {
setState(() {
isPlaying = !isPlaying;
isPlaying ? controller.forward() : controller.reverse();
});
}
}
Use Animated Container with visibility
see this for animated container
Visibility(
visible:true,//controll to click on your lap button
child: AnimatedContainer(),
)
Animated Container
I used AnimatedContainer to animate the stopwatch and fixed the animation issue by removing the padding property from the container and replacing it with a margin property