Почему размер контейнера изменяется сверху и снизу одновременно, а также слева и справа одновременно?

#flutter #dart #flutter-layout #flutter-web #dart-null-safety

Вопрос:

Я пытаюсь создать контейнер с изменяемым размером, который может принимать дочернее устройство, которое затем будет изменяться с любой стороны одновременно. Но, перетаскивая с одной стороны, также перетаскивайте противоположную сторону. То есть при перетаскивании вправо также перетаскивается левая сторона. то же самое и с верхом, верхняя сторона тянет за собой нижнюю, наоборот. Пожалуйста, помогите. Приношу извинения за не очень читаемый код.

          
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Material App Bar'),
        ),
        body: Center(
          child: ResizeableContainer(
            currentHeight: 200,
            currentWidth: 200,
            child: Container(
              color: Colors.yellow,
            ),
          ),
        ),
      ),
    );
  }
}

enum ReferenceSide {
  top,
  bottom,
  left,
  right,
}

double referenceThickness = 4.0;

class ResizeableContainer extends StatefulWidget {
  ResizeableContainer({
    Key? key,
    required this.currentHeight,
    required this.currentWidth,
    required this.child,
  }) : super(key: key);
  double currentWidth;
  double currentHeight;
  Widget child;
  @override
  _ResizeableContainerState createState() => _ResizeableContainerState();
}

class _ResizeableContainerState extends State<ResizeableContainer> {
  @override
  Widget build(BuildContext context) {
    void onHorizontalDragLeft(DragUpdateDetails details) {
      setState(() {
        widget.currentWidth -= details.delta.dx;
      });
    }

    void onHorizontalDragRight(DragUpdateDetails details) {
      setState(() {
        //widget.currentWidth  = details.delta.dx;
        widget.currentWidth  = details.delta.dx;
      });
    }

    void onVerticalDragUp(DragUpdateDetails details) {
      setState(() {
        widget.currentHeight -= details.delta.dy;
        widget.currentHeight > 0 ? widget.currentHeight : 0;
      });
    }

    void onVerticalDragDown(DragUpdateDetails details) {
      setState(() {
        widget.currentHeight  = details.delta.dy;
        widget.currentHeight > 0 ? widget.currentHeight : 0;
      });
    }

    return SizedBox(
      width: widget.currentWidth.clamp(4, 800),
      height: widget.currentHeight.clamp(4, 800),
      child: Stack(
        children: [
          widget.child,
          _DragReferences(
            length: widget.currentWidth,
            side: ReferenceSide.top,
            onDragCallBack: onVerticalDragUp,
          ),
          _DragReferences(
            length: widget.currentWidth,
            side: ReferenceSide.bottom,
            onDragCallBack: onVerticalDragDown,
          ),
          _DragReferences(
            length: widget.currentHeight,
            side: ReferenceSide.left,
            onDragCallBack: onHorizontalDragLeft,
          ),
          _DragReferences(
            length: widget.currentHeight,
            side: ReferenceSide.right,
            onDragCallBack: onHorizontalDragRight,
          )
        ],
      ),
    );
  }
}


class _DragReferences extends StatefulWidget {
  _DragReferences(
      {Key? key, required this.length, required this.side, this.onDragCallBack})
      : super(key: key);

  ReferenceSide side;
  double length;
  void Function(DragUpdateDetails)? onDragCallBack;

  @override
  _DragReferencesState createState() => _DragReferencesState();
}

class _DragReferencesState extends State<_DragReferences> {
  @override
  Widget build(BuildContext context) {
    bool isLeftSide = widget.side == ReferenceSide.left;
    bool isRightSide = widget.side == ReferenceSide.right;
    bool isTopSide = widget.side == ReferenceSide.top;
    bool isBottomSide = widget.side == ReferenceSide.bottom;

    return Positioned(
      left: isRightSide ? null : 0,
      right: isLeftSide ? null : 0,
      top: isBottomSide ? null : 0,
      bottom: isTopSide ? null : 0,
      child: GestureDetector(
        onVerticalDragUpdate:
            isTopSide || isBottomSide ? widget.onDragCallBack : null,
        onHorizontalDragUpdate:
            isLeftSide || isRightSide ? widget.onDragCallBack : null,
        child: _getMouseRegion(side: widget.side, length: widget.length),
      ),
    );
  }
}


Widget _getMouseRegion({required ReferenceSide side, required double length}) {
  bool isVertical = side == ReferenceSide.left || side == ReferenceSide.right;
  return

      
      MouseRegion(
    cursor: isVertical
        ? SystemMouseCursors.resizeLeftRight
        : SystemMouseCursors.resizeUpDown,
    opaque: true,
    child: Container(
      height: isVertical ? length : referenceThickness,
      width: isVertical ? referenceThickness : length,
      color: isVertical ? Colors.amber : Colors.red,
    ),
  );
}
        
 

Ответ №1:

Это происходит потому, что ваш контейнер находится в центре(). Из-за этого Коробка всегда будет находиться на одинаковом расстоянии от левой и правой сторон, и когда вы уменьшаете размер коробки,она также перемещается. Если вы хотите, чтобы контейнер находился в середине экрана, вы можете сделать следующее:

 Center(
   child: SizedBox(
   height: 300, // Or whatever works for you
   width: 300,
   child: ResizeableContainer(
      currentHeight: 200,
      currentWidth: 200,
      child: Container(
         color: Colors.yellow,
      ),
   )
),