【问题标题】:Why is the container resizing from the top and bottom at the side time, as well as left and right at the same time?为什么容器在侧面同时从顶部和底部调整大小,以及同时向左和向右调整?
【发布时间】:2021-11-27 04:56:59
【问题描述】:

我正在尝试构建一个可调整大小的容器,该容器可以容纳一个孩子,然后一次可以从任一侧调整大小。但是,从一侧拖动也会拖动另一侧。即在向右拖动时,左侧也被拖动。与顶部相同,顶部拖动底部,反之亦然。请帮忙。为不那么可读的代码道歉。

         
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,
    ),
  );
}
        

【问题讨论】:

    标签: flutter dart flutter-layout flutter-web dart-null-safety


    【解决方案1】:

    这是因为您的 Container 位于 Center() 中。正因为如此,Box 与左侧和右侧的距离始终相同,并且当您缩小盒子时,它也会重新定位。如果您希望 Container 位于屏幕中间,您可以执行以下操作:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      相关资源
      最近更新 更多