Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save untillnesss/dab9d89ed54d3cbfb02cd6b2c076da3d to your computer and use it in GitHub Desktop.
Save untillnesss/dab9d89ed54d3cbfb02cd6b2c076da3d to your computer and use it in GitHub Desktop.
class ExpandableFloatingActionButton extends StatefulWidget {
final IconData icon;
final String label;
final ScrollController scrollController;
final void Function() onPressed;
const ExpandableFloatingActionButton(
{super.key,
required this.icon,
required this.label,
required this.scrollController,
required this.onPressed});
@override
State<ExpandableFloatingActionButton> createState() =>
_ExpandableFloatingActionButtonState();
}
class _ExpandableFloatingActionButtonState
extends State<ExpandableFloatingActionButton> {
bool _extended = true;
double prevPixelPosition = 0;
@override
void initState() {
super.initState();
widget.scrollController.addListener(_scrollListener);
}
@override
void dispose() {
widget.scrollController.removeListener(_scrollListener);
super.dispose();
}
void _scrollListener() {
if ((prevPixelPosition - widget.scrollController.position.pixels).abs() >
10) {
bool maxScrollReached =
widget.scrollController.position.maxScrollExtent ==
widget.scrollController.position.pixels;
bool scrollUp = widget.scrollController.position.userScrollDirection ==
ScrollDirection.forward;
setState(() => _extended = maxScrollReached || scrollUp);
}
prevPixelPosition = widget.scrollController.position.pixels;
}
@override
Widget build(BuildContext context) {
return FloatingActionButton.extended(
extendedIconLabelSpacing: _extended ? 10 : 0,
extendedPadding:
_extended ? null : const EdgeInsets.symmetric(horizontal: 16),
onPressed: widget.onPressed,
icon: Icon(widget.icon),
label: AnimatedSize(
alignment: Alignment.centerLeft,
duration: const Duration(milliseconds: 200),
child: _extended ? Text(widget.label) : Container(),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment