gpt4 book ai didi

flutter - 如何在 flutter 中调整或调整 Draggable 组件的大小?

转载 作者:IT王子 更新时间:2023-10-29 06:45:19 25 4
gpt4 key购买 nike

如何向可拖动组件添加 anchor (handle),以便通过拖动调整其大小。

enter image description here

最佳答案

我认为此 SO post 中提供的示例原型(prototype)将是您想要实现的目标的理想选择。

  1. Draw size handlers and a container;
  2. Use GestureDetector to detect dragging;
  3. Refresh the main container size and coordinates.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text Overflow Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Demo(),
),
);
}
}

class Demo extends StatefulWidget {
@override
_DemoState createState() => _DemoState();
}

class _DemoState extends State<Demo> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(60),
child: ResizebleWidget(
child: Text(
'''I've just did simple prototype to show main idea.
1. Draw size handlers with container;
2. Use GestureDetector to get new variables of sizes
3. Refresh the main container size.''',
),
),
);
}
}

class ResizebleWidget extends StatefulWidget {
ResizebleWidget({required this.child});

final Widget child;
@override
_ResizebleWidgetState createState() => _ResizebleWidgetState();
}

const ballDiameter = 30.0;

class _ResizebleWidgetState extends State<ResizebleWidget> {
double height = 400;
double width = 200;

double top = 0;
double left = 0;

void onDrag(double dx, double dy) {
var newHeight = height + dy;
var newWidth = width + dx;

setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
});
}

@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
top: top,
left: left,
child: Container(
height: height,
width: width,
color: Colors.red[100],
child: widget.child,
),
),
// top left
Positioned(
top: top - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = (dx + dy) / 2;
var newHeight = height - 2 * mid;
var newWidth = width - 2 * mid;

setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top + mid;
left = left + mid;
});
},
),
),
// top middle
Positioned(
top: top - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height - dy;

setState(() {
height = newHeight > 0 ? newHeight : 0;
top = top + dy;
});
},
),
),
// top right
Positioned(
top: top - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = (dx + (dy * -1)) / 2;

var newHeight = height + 2 * mid;
var newWidth = width + 2 * mid;

setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
),
),
// center right
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width + dx;

setState(() {
width = newWidth > 0 ? newWidth : 0;
});
},
),
),
// bottom right
Positioned(
top: top + height - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = (dx + dy) / 2;

var newHeight = height + 2 * mid;
var newWidth = width + 2 * mid;

setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
),
),
// bottom center
Positioned(
top: top + height - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height + dy;

setState(() {
height = newHeight > 0 ? newHeight : 0;
});
},
),
),
// bottom left
Positioned(
top: top + height - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var mid = ((dx * -1) + dy) / 2;

var newHeight = height + 2 * mid;
var newWidth = width + 2 * mid;

setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
),
),
//left center
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width - dx;

setState(() {
width = newWidth > 0 ? newWidth : 0;
left = left + dx;
});
},
),
),
// center center
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
setState(() {
top = top + dy;
left = left + dx;
});
},
),
),
],
);
}
}

class ManipulatingBall extends StatefulWidget {
const ManipulatingBall({Key? key, required this.onDrag});

final Function onDrag;

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

class _ManipulatingBallState extends State<ManipulatingBall> {
late double initX;
late double initY;

_handleDrag(details) {
setState(() {
initX = details.globalPosition.dx;
initY = details.globalPosition.dy;
});
}

_handleUpdate(details) {
var dx = details.globalPosition.dx - initX;
var dy = details.globalPosition.dy - initY;
initX = details.globalPosition.dx;
initY = details.globalPosition.dy;
widget.onDrag(dx, dy);
}

@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: _handleDrag,
onPanUpdate: _handleUpdate,
child: Container(
width: ballDiameter,
height: ballDiameter,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.5),
shape: BoxShape.circle,
),
),
);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DoubleProperty('initX', initX));
}
}

输出:

enter image description here

关于flutter - 如何在 flutter 中调整或调整 Draggable 组件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55739713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com