fix FAB once and for all

This commit is contained in:
Kenton Hamaluik
2020-03-29 16:31:59 -06:00
parent 67b42683d2
commit ad664f602f
5 changed files with 177 additions and 122 deletions

View File

@ -217,11 +217,12 @@ class MockDataProvider extends DataProvider {
Future<void> editProject(Project project) async {}
Future<void> deleteProject(Project project) async {}
Future<TimerEntry> createTimer({String description, int projectID, DateTime startTime, DateTime endTime}) async {
DateTime st = startTime ?? DateTime.now();
return TimerEntry(
id: -1,
description: description,
projectID: projectID,
startTime: startTime,
startTime: st,
endTime: endTime,
);
}

View File

@ -14,11 +14,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_speed_dial_material_design/flutter_speed_dial_material_design.dart';
//import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:timecop/blocs/timers/bloc.dart';
import 'package:timecop/screens/dashboard/bloc/dashboard_bloc.dart';
import 'package:timecop/screens/dashboard/components/StartTimerSpeedDial.dart';
class StartTimerButton extends StatefulWidget {
StartTimerButton({Key key}) : super(key: key);
@ -28,14 +27,6 @@ class StartTimerButton extends StatefulWidget {
}
class _StartTimerButtonState extends State<StartTimerButton> {
bool _speedDialOpened;
@override
void initState() {
super.initState();
_speedDialOpened = false;
}
@override
Widget build(BuildContext context) {
final DashboardBloc bloc = BlocProvider.of<DashboardBloc>(context);
@ -63,114 +54,13 @@ class _StartTimerButtonState extends State<StartTimerButton> {
onPressed: () {
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
assert(timers != null);
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
bloc.add(TimerWasStartedEvent());
},
);
}
else {
/*return SpeedDial(
marginRight: 14,
overlayColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: _speedDialOpened ? Theme.of(context).disabledColor : Theme.of(context).accentColor,
foregroundColor: Theme.of(context).accentIconTheme.color,
onOpen: () => setState(() => _speedDialOpened = true),
onClose: () => setState(() => _speedDialOpened = false),
child: Stack(
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 15,
left: 16,
child: Icon(FontAwesomeIcons.stopwatch),
)
],
),
children: <SpeedDialChild>[
SpeedDialChild(
child: Icon(FontAwesomeIcons.plus),
backgroundColor: Theme.of(context).accentColor,
foregroundColor: Theme.of(context).accentIconTheme.color,
onTap: () {
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
assert(timers != null);
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
bloc.add(TimerWasStartedEvent());
},
),
SpeedDialChild(
child: Icon(FontAwesomeIcons.stop),
backgroundColor: Colors.pink[600],
foregroundColor: Theme.of(context).accentIconTheme.color,
onTap: () {
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
assert(timers != null);
timers.add(StopAllTimers());
},
),
],
);*/
return SpeedDialFloatingActionButton(
onAction: (int action) {
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
assert(timers != null);
switch(action) {
case 0: {
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
bloc.add(TimerWasStartedEvent());
}
break;
case 1: {
timers.add(StopAllTimers());
}
break;
}
},
actions: <SpeedDialAction>[
SpeedDialAction(
child: Icon(
FontAwesomeIcons.plus,
color: Theme.of(context).accentColor,
)
),
SpeedDialAction(
child: Icon(
FontAwesomeIcons.stop,
color: Colors.pink[600],
),
)
],
childOnFold: Stack(
key: UniqueKey(),
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 15,
left: 16,
child: Icon(FontAwesomeIcons.stopwatch),
)
],
),
childOnUnfold: Stack(
key: UniqueKey(),
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 15,
left: 16,
child: Icon(FontAwesomeIcons.times),
)
],
),
);
return StartTimerSpeedDial();
}
}
);

View File

@ -0,0 +1,173 @@
// Copyright 2020 Kenton Hamaluik
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:timecop/blocs/timers/bloc.dart';
import 'package:timecop/screens/dashboard/bloc/dashboard_bloc.dart';
class StartTimerSpeedDial extends StatefulWidget {
StartTimerSpeedDial({Key key}) : super(key: key);
@override
_StartTimerSpeedDialState createState() => _StartTimerSpeedDialState();
}
class _StartTimerSpeedDialState extends State<StartTimerSpeedDial> with TickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 100),
);
}
@override
Widget build(BuildContext context) {
final DashboardBloc bloc = BlocProvider.of<DashboardBloc>(context);
assert(bloc != null);
// adapted from https://stackoverflow.com/a/46480722
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 70.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: ScaleTransition(
scale: CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
1.0,
curve: Curves.easeOut
),
),
child: FloatingActionButton(
heroTag: null,
mini: true,
child: Stack(
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 7.5,
left: 8,
child: Icon(FontAwesomeIcons.plus),
)
],
),
backgroundColor: Theme.of(context).accentColor,
foregroundColor: Theme.of(context).accentIconTheme.color,
onPressed: () {
_controller.reverse();
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
assert(timers != null);
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
bloc.add(TimerWasStartedEvent());
},
),
),
),
Container(
height: 70.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: ScaleTransition(
scale: CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.75,
curve: Curves.easeOut
),
),
child: FloatingActionButton(
heroTag: null,
mini: true,
child: Stack(
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 7,
left: 7.5,
child: Icon(FontAwesomeIcons.stop),
)
],
),
backgroundColor: Colors.pink[600],
foregroundColor: Theme.of(context).accentIconTheme.color,
onPressed: () {
_controller.reverse();
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
assert(timers != null);
timers.add(StopAllTimers());
},
),
),
),
AnimatedBuilder(
animation: _controller,
builder: (BuildContext conext, Widget child) {
return
FloatingActionButton(
heroTag: null,
backgroundColor: _controller.isDismissed ? Theme.of(context).accentColor : Theme.of(context).disabledColor,
child: _controller.isDismissed
? Stack(
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 15,
left: 16,
child: Icon(FontAwesomeIcons.stopwatch,),
)
],
)
: Stack(
// shenanigans to properly centre the icon (font awesome glyphs are variable
// width but the library currently doesn't deal with that)
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 15,
left: 16,
child: Icon(FontAwesomeIcons.times),
)
],
),
onPressed: () {
if (_controller.isDismissed) {
_controller.forward();
} else {
_controller.reverse();
}
},
);
},
),
]
);
}
}

View File

@ -212,13 +212,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.4"
flutter_speed_dial_material_design:
dependency: "direct main"
description:
name: flutter_speed_dial_material_design
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
flutter_svg:
dependency: "direct main"
description:

View File

@ -27,8 +27,6 @@ dependencies:
path_provider: ^1.6.1
shared_preferences: ^0.5.6+2
fluent: ^1.0.1+2
#flutter_speed_dial: ^1.2.5
flutter_speed_dial_material_design: ^1.1.1
fl_chart: ^0.8.3
flutter_swiper: ^1.1.6