TF-248 Change floating button compose email
This commit is contained in:
@@ -41,6 +41,7 @@ export 'presentation/views/dialog/loading_dialog_builder.dart';
|
||||
export 'presentation/views/dialog/downloading_file_dialog_builder.dart';
|
||||
export 'presentation/views/background/background_widget_builder.dart';
|
||||
export 'presentation/views/html_viewer/html_content_viewer_widget.dart';
|
||||
export 'presentation/views/floating_button/scrolling_floating_button_animated.dart';
|
||||
|
||||
// Resources
|
||||
export 'presentation/resources/assets_paths.dart';
|
||||
|
||||
@@ -50,6 +50,7 @@ class ImagePaths {
|
||||
String get icChevronDown => _getImagePath('ic_chevron_down.svg');
|
||||
String get icFilter => _getImagePath('ic_filter.svg');
|
||||
String get icSearchBar => _getImagePath('ic_search_bar.svg');
|
||||
String get icCompose => _getImagePath('ic_compose.svg');
|
||||
|
||||
String _getImagePath(String imageName) {
|
||||
return AssetsPaths.images + imageName;
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
/// Widget to animate the button when scroll down
|
||||
class ScrollingFloatingButtonAnimated extends StatefulWidget {
|
||||
/// Function to use when press the button
|
||||
final GestureTapCallback? onPress;
|
||||
|
||||
/// Double value to set the button elevation
|
||||
final double? elevation;
|
||||
|
||||
/// Double value to set the button width
|
||||
final double? width;
|
||||
|
||||
/// Double value to set the button height
|
||||
final double? height;
|
||||
|
||||
/// Value to set the duration for animation
|
||||
final Duration? duration;
|
||||
|
||||
/// Widget to use as button icon
|
||||
final Widget? icon;
|
||||
|
||||
/// Widget to use as button text when button is expanded
|
||||
final Widget? text;
|
||||
|
||||
/// Value to set the curve for animation
|
||||
final Curve? curve;
|
||||
|
||||
/// ScrollController to use to determine when user is on top or not
|
||||
final ScrollController? scrollController;
|
||||
|
||||
/// Double value to set the boundary value when scroll animation is triggered
|
||||
final double? limitIndicator;
|
||||
|
||||
/// Color to set the button background color
|
||||
final Color? color;
|
||||
|
||||
/// Value to indicate if animate or not the icon
|
||||
final bool? animateIcon;
|
||||
|
||||
ScrollingFloatingButtonAnimated(
|
||||
{Key? key,
|
||||
required this.icon,
|
||||
required this.text,
|
||||
required this.onPress,
|
||||
required this.scrollController,
|
||||
this.elevation = 5.0,
|
||||
this.width = 120.0,
|
||||
this.height = 60.0,
|
||||
this.duration = const Duration(milliseconds: 250),
|
||||
this.curve,
|
||||
this.limitIndicator = 10.0,
|
||||
this.color = Colors.blueAccent,
|
||||
this.animateIcon = true})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_ScrollingFloatingButtonAnimatedState createState() =>
|
||||
_ScrollingFloatingButtonAnimatedState();
|
||||
}
|
||||
|
||||
class _ScrollingFloatingButtonAnimatedState
|
||||
extends State<ScrollingFloatingButtonAnimated>
|
||||
with SingleTickerProviderStateMixin {
|
||||
/// Boolean value to indicate when scroll view is on top
|
||||
bool _onTop = true;
|
||||
|
||||
/// Value to indicate when to show the child widget
|
||||
bool _visibleText = false;
|
||||
|
||||
/// Controller for icon animation
|
||||
late AnimationController _animationController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_animationController = new AnimationController(
|
||||
vsync: this,
|
||||
duration: Duration(milliseconds: 250),
|
||||
reverseDuration: Duration(milliseconds: 250),
|
||||
animationBehavior: AnimationBehavior.normal,
|
||||
lowerBound: 0,
|
||||
upperBound: 120,
|
||||
);
|
||||
super.initState();
|
||||
_handleScroll();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.scrollController!.removeListener(() {});
|
||||
_animationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// Function to add listener for scroll
|
||||
void _handleScroll() {
|
||||
ScrollController _scrollController = widget.scrollController!;
|
||||
_scrollController.addListener(() {
|
||||
print(_scrollController.position.userScrollDirection);
|
||||
if (_scrollController.position.pixels > widget.limitIndicator! &&
|
||||
_scrollController.position.userScrollDirection ==
|
||||
ScrollDirection.reverse) {
|
||||
if (widget.animateIcon!) _animationController.forward();
|
||||
setState(() {
|
||||
_onTop = false;
|
||||
});
|
||||
} else if (_scrollController.position.pixels <= widget.limitIndicator! &&
|
||||
_scrollController.position.userScrollDirection ==
|
||||
ScrollDirection.forward) {
|
||||
if (widget.animateIcon!) _animationController.reverse();
|
||||
setState(() {
|
||||
_onTop = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
elevation: widget.elevation,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(widget.height! / 2))),
|
||||
child: AnimatedContainer(
|
||||
curve: widget.curve ?? Curves.easeInOut,
|
||||
duration: widget.duration!,
|
||||
height: widget.height,
|
||||
width: _onTop ? widget.width : widget.height,
|
||||
onEnd: () {
|
||||
setState(() {
|
||||
_visibleText = !_visibleText;
|
||||
});
|
||||
},
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(widget.height! / 2))),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.all(Radius.circular(widget.height! / 2)),
|
||||
onTap: widget.onPress,
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(widget.height! / 2)),
|
||||
color: widget.color),
|
||||
child: Row(
|
||||
mainAxisAlignment: _onTop ? MainAxisAlignment.spaceEvenly : MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 16, right: _onTop ? 10 : 16),
|
||||
child: AnimatedBuilder(
|
||||
child: widget.icon!,
|
||||
animation: _animationController,
|
||||
builder: (BuildContext context, Widget? _widget) {
|
||||
return Transform.rotate(
|
||||
angle: (_animationController.value * 3 * math.pi) / 180,
|
||||
child: _widget!,
|
||||
);
|
||||
}),
|
||||
),
|
||||
...(_onTop
|
||||
? [
|
||||
Expanded(
|
||||
child: AnimatedOpacity(
|
||||
opacity: !_visibleText ? 1 : 0,
|
||||
duration: const Duration(milliseconds: 100),
|
||||
child: widget.text!,
|
||||
),
|
||||
)
|
||||
]
|
||||
: []),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user