我正在开发一个类似绘画的应用程序,可以使用点击坐标绘制线条和形状。我需要获取画布中绘制的线条的角度或度数。使用 CustomPaint 绘制线条并使用 XGestureDetector 获取 onTap 坐标。
我需要实现上述目标。
这是我的代码,
class LandingScreen extends State<MyApp> {
LandingScreen(List<List<Offset>> connectionList);
@override
void initState() {
XGesture();
super.initState();
}
@override
Widget build(BuildContext context) {
late List<List<Offset>> _connectionList;
_connectionList = [[Offset(104.0, 242.6), Offset(101.4, 559.3)], [Offset(238.9, 238.6), Offset(229.8, 440.4)]];
String dropdownvalue = 'Square';
var items = ['Square', ' Circle ', ' Rectangle ', ' Circle ',];
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body:
XGesture(),
),
);
}
}
class XGesture extends StatefulWidget {
late List<List<Offset>> connectionListRedo = [];
@override
_XGestureState createState() => _XGestureState();
}
class _XGestureState extends State<XGesture> {
late MoveEvent pos1;
late MoveEvent pos2;
late List<List<Offset>> _connectionList;
late List<List<Offset>> connectionListRedo1;
_XGestureState();
@override
void initState() {
onMoveStart;
pos1 = MoveEvent(Offset(0.0, 0.0), Offset(0.0, 0.0), 0);
pos2 = MoveEvent(Offset(0.0, 0.0), Offset(0.0, 0.0), 0);
_connectionList = [];
onMoveEnd;
LandingScreen(_connectionList);
super.initState();
}
@override
Widget build(BuildContext context) {
String dropdownvalue = 'Square';
var items = [
'Square',
' Circle ',
' Rectangle ',
' Circle ',
];
String dropdownvalue1 = 'Teams';
var items1 = [
'Teams',
' Sluggers ',
' Lakes ',
' Add More ',
];
final x = Angle.degrees(180.0);
debugPrint('Angle of x : ${x.degrees}');
return XGestureDetector(
child: Material(
color: Colors.black87,
child: Center(
child: CustomPaint(
painter: LinePainter(pos1.localPos, pos2.localPos, _connectionList),
child:SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.green, width: 4),
color: Color(0xDC063280),
),
child: TextButton.icon(
label: const Text('Undo', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
icon: Icon(Icons.undo, color: Colors.white,),
onPressed: () {
widget.connectionListRedo.add(_connectionList.last);
debugPrint('Not Removed Offset List value: ${widget.connectionListRedo}');
_connectionList.removeLast();
debugPrint('Removed Offset List value: $_connectionList');
print('Pressed Undo btn');
}),
),
),
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.green, width: 4),
color: Color(0xDC063280),
),
child: TextButton.icon(
label: const Text('Redo', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
icon: Icon(Icons.redo, color: Colors.white,),
onPressed: () {
debugPrint('Not Removed Offset List value in Redo: ${widget.connectionListRedo}');
_connectionList.add(widget.connectionListRedo.last);
widget.connectionListRedo.removeLast();
debugPrint('Retrieved Offset value Redo: $_connectionList');
print('Pressed Undo btn');
}),
),
),
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.green, width: 4),
color: Color(0xDC063280),
),
child:
TextButton.icon(
label: const Text('Line', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
icon: Icon(Icons.create, color: Colors.white),
onPressed: () {
print('Pressed Line btn');
})
),
),
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 3.5,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.green, width: 4),
color: Color(0xDC063280),
),
child:
DropdownButton(
icon: const Icon(Icons.arrow_drop_down, color: Colors.white, size: 30,),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
value: dropdownvalue,
dropdownColor: Colors.redAccent,
items: items.map((String items) {
return DropdownMenuItem(child: Text(items),
value: items,
);
}).toList(),
onChanged: (String? value){
setState(() {
dropdownvalue = value!;
});
},
),
),
),
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.green, width: 4),
color: Color(0xDC063280),
),
child: TextButton.icon(
label: const Text('My Videos', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
icon: Icon(Icons.image, color: Colors.white,),
onPressed: () {
print('Pressed Video btn');
}),
),
),
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 0.0,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.green, width: 4),
color: Color(0xDC063280),
),
child:
TextButton.icon(
label: const Text('Notifications', textAlign: TextAlign.justify, style: TextStyle(fontSize: 20, color: Colors.white),),
// icon: Icon(Icons.align_vertical_center_sharp, color: Colors.white),
icon: Icon(Icons.notifications, color: Colors.white),
onPressed: () {
print('Pressed Notifications btn');
})
),
),
Align(
alignment: FractionalOffset.bottomLeft,
child:
Container(
padding: EdgeInsets.only(top: 0.5,bottom: 0.5,left: 3.5,right: 0.0),
decoration:BoxDecoration(
borderRadius:BorderRadius.circular(5),
border: Border.all(color: Colors.redAccent, width: 4),
color:Colors.black87
),
child:
DropdownButton(
icon: const Icon(Icons.arrow_drop_down, color: Colors.white, size: 30,),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
value: dropdownvalue1,
dropdownColor: Colors.redAccent,
items: items1.map((String items) {
return DropdownMenuItem(child: Text(items),
value: items,
);
}).toList(),
onChanged: (String? value){
setState(() {
dropdownvalue1 = value!;
});
},
),
),
),
],
),
),
)),
),
doubleTapTimeConsider: 300,
longPressTimeConsider: 350,
onTap: onTap,
onMoveStart: onMoveStart,
onMoveEnd: onMoveEnd,
onMoveUpdate: onMoveUpdate,
onScaleStart: onScaleStart,
onScaleUpdate: onScaleUpdate,
onScaleEnd: onScaleEnd,
bypassTapEventOnDoubleTap: false,
);
}
void onScaleEnd() {
setLastEventName('onScaleEnd');
print('onScaleEnd');
}
void onScaleStart(initialFocusPoint) {
setLastEventName('onScaleStart');
print('onScaleStart - initialFocusPoint: ' + initialFocusPoint.toString());
}
void onLongPress(pointer, localPos, position) {
setLastEventName('onLongPress');
print('onLongPress - pos: ' + localPos.toString());
}
void onDoubleTap(localPos, position) {
setLastEventName('onDoubleTap');
print('onDoubleTap - pos: ' + localPos.toString());
_connectionList.removeLast();
}
void onTap(event) {
setLastEventName('onTap');
print('onTap - pos: ' + event.localPos.toString());
}
Future<void> onMoveUpdate(MoveEvent event) async {
setLastEventName('onMoveUpdate');
print('onMoveUpdate - pos: ${event.localPos} delta: ${event.delta}');
}
void onMoveStart(localPos) {
setLastEventName('onMoveStart');
print('onMoveStart - pos: $localPos');
pos1 = localPos;
debugPrint('pos1 Local pos: ${pos1.localPos}');
debugPrint('pos1 delta pos: ${pos1.delta}');
}
void onMoveEnd(localPos) {
setLastEventName('onMoveEnd');
print('onMoveEnd - pos: $localPos');
pos2 = localPos;
debugPrint('pos2 Local pos: ${pos2.localPos}');
debugPrint('position1 ${pos1.localPos}, position2 ${pos2.localPos}');
List<Offset> _offsets = [];
_offsets.add(pos1.localPos);
_offsets.add(pos2.localPos);
_connectionList.add(_offsets);
widget.connectionListRedo = [];
debugPrint('Offset List value: ${_offsets}, List: $_connectionList');
LinePainter(pos1.localPos, pos2.localPos, _connectionList);
}
void onScaleUpdate(ScaleEvent event) {
setLastEventName('onScaleUpdate');
print(
'onScaleUpdate - changedFocusPoint: ${event.focalPoint} ; scale: ${event.scale} ;Rotation: ${event.rotationAngle}');
}
}
由于我是 Flutter 新手,所以会有一些不需要的代码。请忽略那些。