为啥容器在侧面同时从顶部和底部调整大小,以及同时向左和向右调整?
Posted
技术标签:
【中文标题】为啥容器在侧面同时从顶部和底部调整大小,以及同时向左和向右调整?【英文标题】: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,
),
);
【问题讨论】:
【参考方案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,
),
)
),
【讨论】:
以上是关于为啥容器在侧面同时从顶部和底部调整大小,以及同时向左和向右调整?的主要内容,如果未能解决你的问题,请参考以下文章