如何获得拖动对象的左上角?
下面的代码可以直接在 web 中测试。它在渲染后打印尺寸和一些奇怪的(没用的?)翻译值。我想将矩形与网格对齐。
import 'package:flutter/material.dart';
List<DBTableView> tableViews = [];
void main() {
tableViews = [
DBTableView(
table: DBTable()
..name = 'user'
..columns = ['id bigserial', 'name text']
..offset = const Offset(50, 50),
),
DBTableView(
table: DBTable()
..name = 'role'
..columns = ['id bigserial', 'role char(20)']
..offset = const Offset(100, 100),
),
];
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ER-Modeler',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int counter = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('ER-Modeler')),
body: GridPaper(
interval: 50,
child: DragTarget<DBTableView>(
onAcceptWithDetails: (DragTargetDetails<DBTableView> details) =>
_onDrop(details),
onWillAccept: (_) => true,
builder: (BuildContext ctx, List<Object?> candidateData,
List<dynamic> rejectedData) =>
Stack(
children: tableViews,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(
() => tableViews.add(
DBTableView(
table: DBTable()
..name = 'Table #$counter'
..columns = ['id bigserial', 'name text']),
),
),
tooltip: 'Add Table',
child: const Icon(Icons.add),
),
);
}
_onDrop(DragTargetDetails<DBTableView> details) {
GlobalKey key = details.data.table.key;
Size? size = key.currentContext?.size;
if (size != null) {
print('size = $size');
}
print('old position = ${details.data.table.offset}');
key.currentState?.setState(() => null);
details.data.table.offset = details.offset;
print('new position = ${details.data.table.offset}');
RenderObject? renderObject = key.currentContext?.findRenderObject();
if (renderObject != null) {
var translation = renderObject.getTransformTo(null).getTranslation();
print('translation: x=${translation.x}, y= ${translation.y}');
}
}
}
class DBTable {
GlobalKey key = GlobalKey();
Offset offset = const Offset(0, 0);
String name = '';
List<String> columns = [];
}
class DBTableView extends StatefulWidget {
final DBTable table;
DBTableView({required this.table}) : super(key: table.key);
@override
State<StatefulWidget> createState() => _DBTableViewState();
}
class _DBTableViewState extends State<DBTableView> {
@override
Widget build(BuildContext context) {
return Positioned(
left: widget.table.offset.dx,
top: widget.table.offset.dy,
child: Draggable(
data: widget,
child: _buildChild(DragWidgetType.child),
childWhenDragging: _buildChild(DragWidgetType.childLeft),
feedback: Material(
child: _buildChild(DragWidgetType.feedback),
),
),
);
}
Widget _buildChild(DragWidgetType type) {
return Container(
decoration: BoxDecoration(
border: Border.all(),
color: (type == DragWidgetType.child)
? Colors.amberAccent.shade200
: (type == DragWidgetType.childLeft)
? Colors.black26
: Colors.yellowAccent,
),
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('- ${widget.table.name} -'),
for (String col in widget.table.columns) Text(col),
],
),
);
}
}
enum DragWidgetType { child, childLeft, feedback }