#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,
),
)
),