我目前正在使用一个ScreenView,它具有诸如可拖动和可调整大小的视图等功能,如上图所示,带有角和边。现在的问题是我想通过角落的触摸手势来调整视图的大小。因此,我想到了一个点,可以将其添加到选择视图中,可以将其拖动以调整所选视图的大小。
即使经过长时间的研究,我也无法提出如何叠加另一个具有自己的DragListener的视图的解决方案。有人有这个问题的经验吗?预先谢谢你。
Resizable-Widget演示
ReactNative Demo: React Native PLUGIN example
JS DEMO(转到缩放部分): JS Example, GOTO RESIZING section
使用@Kherel示例的修改代码。
import 'package:flutter/material.dart';
class DrawResizableWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text Overflow Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: DemoWidget(),
backgroundColor: Colors.black,
),
);
}
}
class DemoWidget extends StatefulWidget {
@override
_DemoWidgetState createState() => _DemoWidgetState();
}
class _DemoWidgetState extends State<DemoWidget> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.only(top: 30),
child: ResizebleWidget(
child:
// Image.asset('assets/blur.jpg'),
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({this.child});
final Widget child;
@override
_ResizebleWidgetState createState() => _ResizebleWidgetState();
}
const ballDiameter = 20.0;
class _ResizebleWidgetState extends State<ResizebleWidget> {
double height = 400;
double width = 200;
Function onDragStart(String name) => (dx, 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 Container(
height: height + ballDiameter / 2,
width: width + ballDiameter / 2,
alignment: Alignment.center,
child: Stack(
children: <Widget>[
Positioned(
top: 0,
left: 0,
child: Container(
height: height,
width: width,
color: Colors.white70,
child: widget.child,
),
),
Positioned(
right: 0,
bottom: 0,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
Positioned(
right: width / 2,
bottom: 0,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
Positioned(
right: 0,
bottom: height / 2,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
Positioned(
top: 0,
left: width,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
Positioned(
top: 0,
left: 0,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
Positioned(
left: 0,
top: height / 2,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
Positioned(
left: 0,
top: height - 10,
child: ManipulatingBall(
onDragStart: onDragStart('start'),
),
),
],
),
);
}
}
class ManipulatingBall extends StatefulWidget {
ManipulatingBall({Key key, this.onDragStart});
final Function onDragStart;
@override
_ManipulatingBallState createState() => _ManipulatingBallState();
}
class _ManipulatingBallState extends State<ManipulatingBall> {
double initX;
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.onDragStart(dx, dy);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: _handleDrag,
onPanUpdate: _handleUpdate,
child: Container(
width: ballDiameter,
height: ballDiameter,
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.5),
shape: BoxShape.circle,
),
),
);
}
}
当前代码输出:
当前问题:
从像左上角的角落拖动不起作用。
ManipulatingBall不是确切的角。
无法像所有侧面的中间部分一样使矩形处理程序。
更新
我制作了一个简单的原型来展示这个想法。
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({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 newHeight = height - dy;
var newWidth = width - dx;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top + dy;
left = left + dx;
});
},
),
),
// 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 newHeight = height - dy;
var newWidth = width + dx;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top + dy;
});
},
),
),
// 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 newHeight = height + dy;
var newWidth = width + dx;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
});
},
),
),
// 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 newHeight = height + dy;
var newWidth = width - dx;
setState(() {
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
left = left + dx;
});
},
),
),
//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 {
ManipulatingBall({Key key, this.onDrag});
final Function onDrag;
@override
_ManipulatingBallState createState() => _ManipulatingBallState();
}
class _ManipulatingBallState extends State<ManipulatingBall> {
double initX;
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,
),
),
);
}
}