New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support extended FABs collapsing into a FAB #104393
Comments
cc: @guidezpl |
Added to the tracking issue. |
I wonder if this issue could be a bit broader so the M3 FAB can support a wider variety of transformations. The Material spec states:
Maybe this should be a separate issue, but it seems like the extended/collapsed transition is just a subset of a broader need for FAB transformations and it might be better to tackle the whole problem all at once. |
247377707-373d9324-c495-41de-ba9c-6cf70975d783.mp4Animating the bottom bar while scrolling is also very good, and it is recommended to consider adding this feature as well |
Is this a video of an implementation of yours? I tried implementing it myself by switching between FloatingActionButton.extended and FloatingActionButton and an AnimatedContainer to animate the width. However I can't get the icon to stay at the same position relative to the FloatingActionButton container. It looks weird :/ |
Here is the widget I use to be close to the material demo
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2023-11-04.at.16.10.05.mp4 |
Your answer works, thank you |
To make this more stable I've added 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(),
),
);
}
} Thanks so much! |
Reference: https://m3.material.io/components/floating-action-button/guidelines
part of #91605
l0js5c2i-efab_.scrolling_3P.mp4
The text was updated successfully, but these errors were encountered: