Skip to content

Instantly share code, notes, and snippets.

@naveenadi
Forked from xSaCh/expandable_widget.dart
Created March 3, 2025 08:12
Show Gist options
  • Save naveenadi/776bd57f87acd806f7168e14975b3a52 to your computer and use it in GitHub Desktop.
Save naveenadi/776bd57f87acd806f7168e14975b3a52 to your computer and use it in GitHub Desktop.
Flutter Widget allow child to grow / shrink based on userdrag. DragWidget's gesture will be prioritize that it's parents even if parent is scrollable like SingleChildScrollView.
import 'package:flutter/material.dart';
class ExpandableWidget extends StatefulWidget {
const ExpandableWidget({
super.key,
required this.child,
required this.dragWidget,
this.initHeight,
this.maxHeight,
this.minHeight,
this.onScrollChange,
this.dragWidgetOffset,
this.dragWidgetPadding = const EdgeInsets.all(8),
});
final Widget child;
final Widget dragWidget;
final double? initHeight;
final double? maxHeight;
final double? minHeight;
final Offset? dragWidgetOffset;
final EdgeInsets? dragWidgetPadding;
final Function(bool isScrolling)? onScrollChange;
@override
ExpandableWidgetState createState() => ExpandableWidgetState();
}
class ExpandableWidgetState extends State<ExpandableWidget> {
double _currentHeight = 0, _maxHeight = 0, _minHeight = 0;
@override
void initState() {
_minHeight = widget.minHeight ?? 100; // default min height as needed
_currentHeight = widget.initHeight ?? _minHeight;
_maxHeight = widget.maxHeight ?? double.infinity;
super.initState();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
SizedBox(height: _currentHeight, child: widget.child),
Positioned(
bottom: 0 + (widget.dragWidgetOffset?.dy ?? 0),
right: 0 + (widget.dragWidgetOffset?.dx ?? 0),
child: Listener(
onPointerUp: (event) => widget.onScrollChange?.call(false),
onPointerDown: (event) => widget.onScrollChange?.call(true),
onPointerMove: (event) {
_currentHeight += event.delta.dy;
setState(() {
_currentHeight = _currentHeight.clamp(_minHeight, _maxHeight);
});
},
child: Container(
padding: widget.dragWidgetPadding,
child: widget.dragWidget,
),
),
),
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment