Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter : Change size of stack when children overflow

Tags:

flutter

dart

Stac Simulation

I have a draggable widget (from https://medium.com/flutter-community/create-a-draggable-widget-in-flutter-50b61f12635d ) with a stack in a container (red color) consists of moveable children. Here is the widget tree: widget tree

I wanted to add a Gesture Transformations as FormBuilder ( https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/transformations/transformations_demo.dart ) to transform the matrix, as you can see in the GIF, mainly zoom in/out and transform x/y.

class _HomeViewState extends State<HomeView> {
  final _stackKey;
  _HomeViewState(this._stackKey);
  List<Widget> movableItems = [];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text('SynApp'),
        actions: <Widget>[
          IconButton(
            onPressed: () {
              x = 200.0;
              y = 200.0;
              setState(() {
                movableItems.add(
                  MoveableStackItem(_stackKey),
                );
              });
            },
            icon: Icon(Icons.add),
          ),
        ],
      ),
      body: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
        // Draw the scene as big as is available, but allow the user to
        // translate beyond that to a visibleSize that's a bit bigger.
        final Size size = Size(constraints.maxWidth, constraints.maxHeight);
        final Size visibleSize = Size(size.width * 3, size.height * 2);
        return GestureTransformable(
          reset: _reset,

          onResetEnd: () {
            setState(() {
              _reset = false;
            });
          },
          child: new Container(
            color: Colors.red,
            child: Stack(
                key: _stackKey,
                overflow: Overflow.visible,
                fit: StackFit.expand,
                children: movableItems),
          ),


          boundaryRect: Rect.fromLTWH(
            -visibleSize.width / 2,
            -visibleSize.height / 2,
            visibleSize.width,
            visibleSize.height,
          ),

          initialTranslation: Offset(size.width, size.height),
          size: size,
        );
      }),
    );
  }
}

The problem is:

a) the size of the stack is equal to the initial screen.

b)when I move items out of the screen, gestureDetection stops, the items are no longer moveable.

What I want: I want to dynamically resize the size of the stack (the red box) depending on where I move the items.

I was able to find the position and size of the stack widget.


  Size stackSize;
  Offset stackPosition;
  _MoveableStackItemState(this._stackKey);


  getSizeAndPosition() {
    RenderStack _stackStack = _stackKey.currentContext.findRenderObject();
    stackSize = _stackStack.size;
    stackPosition = _stackStack.localToGlobal(Offset.zero);
    print('stackSize $stackSize');
    print('stackPosition $stackPosition');
  }

But I'm starting to get lost in advanced UI object orientated stateful widget manipulation.

like image 882
Mi Be Avatar asked Nov 06 '19 17:11

Mi Be


1 Answers

You can wrap the red stack with an AnimatedContainer.

LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
        // Draw the scene as big as is available, but allow the user to
        // translate beyond that to a visibleSize that's a bit bigger.
        final Size size = Size(constraints.maxWidth, constraints.maxHeight);
        final Size visibleSize = Size(size.width * 3, size.height * 2);
        return GestureTransformable(
          reset: _reset,

          onResetEnd: () {
            setState(() {
              _reset = false;
            });
          },
          child: new AnimatedContainer(
            color: Colors.red,
            duration: Duration(milliseconds: 200),
            width: _stackWidth,
            height: _stackHeight,
            child: Stack(
                key: _stackKey,
                overflow: Overflow.visible,
                fit: StackFit.expand,
                children: movableItems),
          ),


          boundaryRect: Rect.fromLTWH(
            -visibleSize.width / 2,
            -visibleSize.height / 2,
            visibleSize.width,
            visibleSize.height,
          ),

          initialTranslation: Offset(size.width, size.height),
          size: size,
        );
      }),

Try to listen the following event of the GestureTransformable

onPanUpdate: (DragUpdateDetails details){
  var deltaX = details.delta.dx;
  var deltaY = details.delta.dy;
}

DragUpdateDetails object let you to know the delta

the amount the pointer has moved in the coordinate space of the event receiver since the previous update

on the x and y axis.

Inside the "onPanUpdate" you can update the width and the height of the animated container related to the delta of the gesture.

setState((){
  _stackHeight = /* ... */
  _stackWidth = /* ... */
});
like image 101
Caffo17 Avatar answered Nov 08 '22 08:11

Caffo17