Flutter 创建可调整大小的视图,该视图在颤振中从角落和侧面挤压或拖动时可调整大小
我目前正在开发一个屏幕视图,其功能包括可拖动和可调整大小的视图,包括角和边,如上图所示。我现在的问题是,我想通过角落里的触摸手势来调整视图的大小。因此,我想到了一个在选择时添加到视图中的点,可以通过拖动该点来调整选定视图的大小。答案更新 可调整大小的小部件演示: 修改的可行示例:Flutter 创建可调整大小的视图,该视图在颤振中从角落和侧面挤压或拖动时可调整大小,flutter,resize,flutter-layout,image-resizing,window-resize,Flutter,Resize,Flutter Layout,Image Resizing,Window Resize,我目前正在开发一个屏幕视图,其功能包括可拖动和可调整大小的视图,包括角和边,如上图所示。我现在的问题是,我想通过角落里的触摸手势来调整视图的大小。因此,我想到了一个在选择时添加到视图中的点,可以通过拖动该点来调整选定视图的大小。答案更新 可调整大小的小部件演示: 修改的可行示例: import 'package:flutter/material.dart'; class ResizeWidget extends StatefulWidget { @override _R
import 'package:flutter/material.dart';
class ResizeWidget extends StatefulWidget {
@override
_ResizeWidgetState createState() => _ResizeWidgetState();
}
class _ResizeWidgetState extends State<ResizeWidget> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: Container(
// padding: EdgeInsets.only(top: 50),
child: ResizebleWidget(
child: Container(
padding: EdgeInsets.all(10),
child: Text(
'Waao!! you can really dance.',
style: TextStyle(
color: Colors.white,
fontStyle: FontStyle.italic,
fontSize: 18),
),
),
),
),
),
);
}
}
class ResizebleWidget extends StatefulWidget {
ResizebleWidget({this.child});
final Widget child;
@override
_ResizebleWidgetState createState() => _ResizebleWidgetState();
}
const ballDiameter = 10.0;
class _ResizebleWidgetState extends State<ResizebleWidget> {
double height = 100;
double width = 200;
bool isCorner = false;
double top = 0;
double left = 0;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
top: top,
left: left,
child: Container(
height: height,
width: width,
decoration: BoxDecoration(
color: Colors.blueGrey,
border: Border.all(
width: 2,
color: Colors.white70,
),
borderRadius: BorderRadius.circular(0.0),
),
// need tp check if draggable is done from corner or sides
child: isCorner
? FittedBox(
child: widget.child,
)
: Center(
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(() {
isCorner = true;
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top + mid;
left = left + mid;
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
// top middle
Positioned(
top: top - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height - dy;
setState(() {
isCorner = false;
height = newHeight > 0 ? newHeight : 0;
top = top + dy;
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
// 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(() {
isCorner = true;
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
// center right
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + width - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width + dx;
setState(() {
isCorner = false;
width = newWidth > 0 ? newWidth : 0;
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
// 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(() {
isCorner = true;
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
// bottom center
Positioned(
top: top + height - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newHeight = height + dy;
setState(() {
isCorner = false;
height = newHeight > 0 ? newHeight : 0;
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
// 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(() {
isCorner = true;
height = newHeight > 0 ? newHeight : 0;
width = newWidth > 0 ? newWidth : 0;
top = top - mid;
left = left - mid;
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
//left center
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
var newWidth = width - dx;
setState(() {
isCorner = false;
width = newWidth > 0 ? newWidth : 0;
left = left + dx;
});
},
handlerWidget: HandlerWidget.HORIZONTAL,
),
),
// center center
Positioned(
top: top + height / 2 - ballDiameter / 2,
left: left + width / 2 - ballDiameter / 2,
child: ManipulatingBall(
onDrag: (dx, dy) {
setState(() {
isCorner = false;
top = top + dy;
left = left + dx;
});
},
handlerWidget: HandlerWidget.VERTICAL,
),
),
],
);
}
}
class ManipulatingBall extends StatefulWidget {
ManipulatingBall({Key key, this.onDrag, this.handlerWidget});
final Function onDrag;
final HandlerWidget handlerWidget;
@override
_ManipulatingBallState createState() => _ManipulatingBallState();
}
enum HandlerWidget { HORIZONTAL, VERTICAL }
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.white,
shape: this.widget.handlerWidget == HandlerWidget.VERTICAL
? BoxShape.circle
: BoxShape.rectangle,
),
),
);
}
}
导入“包装:颤振/材料.省道”;
类ResizeWidget扩展StatefulWidget{
@凌驾
_ResizeWidgetState createState();
}
类_ResizeWidgetState扩展状态{
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
背景颜色:Colors.black,
主体:容器(
//填充:仅限边缘设置(顶部:50),
孩子:ResizebleWidget(
子:容器(
填充:边缘设置。全部(10),
子:文本(
“哇!!你真会跳舞。”,
样式:TextStyle(
颜色:颜色,白色,
fontStyle:fontStyle.italic,
尺寸:18),,
),
),
),
),
),
);
}
}
类ResizebleWidget扩展StatefulWidget{
ResizebleWidget({this.child});
最后一个孩子;
@凌驾
_ResizebleWidgetState createState()=>\u ResizebleWidgetState();
}
恒球直径=10.0;
类_ResizebleWidgetState扩展状态{
双倍高度=100;
双倍宽度=200;
bool-isCorner=false;
双层顶=0;
左双=0;
@凌驾
小部件构建(构建上下文){
返回堆栈(
儿童:[
定位(
顶:顶,,
左:左,,
子:容器(
高度:高度,,
宽度:宽度,
装饰:盒子装饰(
颜色:颜色。蓝灰色,
边界:边界(
宽度:2,
颜色:颜色。白色70,
),
边界半径:边界半径。圆形(0.0),
),
//需要tp检查是否从角落或侧面进行牵引
孩子:伊斯科纳
?装配箱(
child:widget.child,
)
:中心(
child:widget.child,
),
),
),
//左上角
定位(
顶部:顶部-球径/2,
左:左-球径/2,
孩子:操纵球(
onDrag:(dx,dy){
var-mid=(dx+dy)/2;
var newHeight=高度-2*mid;
var newWidth=宽度-2*mid;
设置状态(){
isCorner=true;
高度=新高度>0?新高度:0;
宽度=新宽度>0?新宽度:0;
顶部=顶部+中间;
左=左+中;
});
},
handlerWidget:handlerWidget.VERTICAL,
),
),
//中上部
定位(
顶部:顶部-球径/2,
左:左+宽度/2-球径/2,
孩子:操纵球(
onDrag:(dx,dy){
var newHeight=高度-dy;
设置状态(){
isCorner=假;
高度=新高度>0?新高度:0;
top=top+dy;
});
},
handlerWidget:handlerWidget.HORIZONTAL,
),
),
//右上角
定位(
顶部:顶部-球径/2,
左:左+宽-球径/2,
孩子:操纵球(
onDrag:(dx,dy){
var-mid=(dx+(dy*-1))/2;
var newHeight=高度+2*mid;
var newWidth=width+2*mid;
设置状态(){
isCorner=true;
高度=新高度>0?新高度:0;
宽度=新宽度>0?新宽度:0;
顶部=顶部-中部;
左=左-中;
});
},
handlerWidget:handlerWidget.VERTICAL,
),
),
//中右翼
定位(
顶部:顶部+高度/2-球径/2,
左:左+宽-球径/2,
孩子:操纵球(
onDrag:(dx,dy){
var newWidth=width+dx;
设置状态(){
isCorner=假;
宽度=新宽度>0?新宽度:0;
});
},
handlerWidget:handlerWidget.HORIZONTAL,
),
),
//右下角
定位(
顶部:顶部+高度-球径/2,
左:左+宽-球径/2,
孩子:操纵球(
onDrag:(dx,dy){
var-mid=(dx+dy)/2;
var newHeight=高度+2*mid;
var newWidth=width+2*mid;
设置状态(){
isCorner=true;
高度=新高度>0?新高度:0;
宽度=新宽度>0?新宽度:0;
顶部=顶部-中部;
左=左-中;
});
},
handlerWidget:handlerWidget.VERTICAL,
),
),
//底部中心
定位(
顶部:顶部+高度-球径/2
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 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 {
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,
),
),
);
}
}