Skip to content

Instantly share code, notes, and snippets.

@xSaCh
Created February 27, 2025 17:43
Show Gist options
  • Select an option

  • Save xSaCh/40b4d1583a0117a87c784b2f4c986ea8 to your computer and use it in GitHub Desktop.

Select an option

Save xSaCh/40b4d1583a0117a87c784b2f4c986ea8 to your computer and use it in GitHub Desktop.

Revisions

  1. xSaCh created this gist Feb 27, 2025.
    69 changes: 69 additions & 0 deletions expandable_widget.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    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,
    ),
    ),
    ),
    ],
    );
    }
    }