gpt4 book ai didi

flutter - 为什么可拖动小部件没有放置在正确的位置?

转载 作者:行者123 更新时间:2023-12-05 04:58:04 28 4
gpt4 key购买 nike

我很难理解为什么在移动一个可拖动的小部件后,它会被放置到比我放置它的位置低 100px 的另一个位置......我唯一能想到的是它增加了 Appbarstatus bar 的高度 ...

我以为我做错了什么,所以我决定尽可能创建最简单的示例,但它仍然在做同样的事情。

只是为了确认,我不想使用拖动目标或类似的东西...我只是希望可拖动的小部件准确地落在我放置东西的地方。但是,我确实需要它在 Stack 中

[编辑] 似乎删除 AppBar 允许 Draggable 准确地落在您放置它的位置。但是,我不希望可拖动小部件位于状态栏后面,因此在添加 SafeArea 之后,我遇到了类似的问题。 [/编辑]

import 'package:flutter/material.dart';

class DraggableTest extends StatefulWidget {
static const routeName = '/draggable-test';
@override
_DraggableTestState createState() => _DraggableTestState();
}

class _DraggableTestState extends State<DraggableTest> {
Offset _dragOffset = Offset(0, 0);

Widget _dragWidget() {
return Positioned(
left: _dragOffset.dx,
top: _dragOffset.dy,
child: Draggable(
child: Container(
height: 120,
width: 90,
color: Colors.black,
),
childWhenDragging: Container(
height: 120,
width: 90,
color: Colors.grey,
),
feedback: Container(
height: 120,
width: 90,
color: Colors.red,
),
onDragEnd: (drag) {
setState(() {
_dragOffset = drag.offset;
});
},
),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Stack(
children: <Widget>[
_dragWidget(),
],
),
);
}
}

最佳答案

主要问题与全局位置与本地位置有关:您的 Draggable 小部件提供全局位置,而 Stack 内的 Positioned 则提供本地位置。当没有 AppBar 全局和本地位置匹配时,问题消失但仍然存在。

所以真正的解决办法是:

  1. 将您的全局坐标转换为本地坐标:
RenderBox renderBox = context.findRenderObject();
onDragEnd(renderBox.globalToLocal(drag.offset));
  1. 您现在需要一个上下文。此上下文必须是本地的(例如 Draggable 的)。因此,在最终实现中,您可以将 Stack 或 Draggable 嵌入到 StatelessWidget 类中,以获得本地上下文。

这是我的最终实现:

import 'package:flutter/material.dart';

main() {
runApp(MaterialApp(
home: DraggableTest(),
));
}

class DraggableTest extends StatefulWidget {
static const routeName = '/draggable-test';

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

class _DraggableTestState extends State<DraggableTest> {
Offset _dragOffset = Offset(0, 0);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Stack(
children: <Widget>[
Positioned(
left: _dragOffset.dx,
top: _dragOffset.dy,
child: DragWidget(onDragEnd: onDragEnd),
),
],
),
);
}

void onDragEnd(Offset offset) {
setState(() {
_dragOffset += offset;
});
}
}

class DragWidget extends StatelessWidget {
final void Function(Offset) onDragEnd;

const DragWidget({Key key, this.onDragEnd}) : super(key: key);

@override
Widget build(BuildContext context) {
return Draggable(
child: Container(
height: 120,
width: 90,
color: Colors.black,
),
childWhenDragging: Container(
height: 120,
width: 90,
color: Colors.grey,
),
feedback: Container(
height: 120,
width: 90,
color: Colors.red,
),
onDragEnd: (drag) {
RenderBox renderBox = context.findRenderObject();
onDragEnd(renderBox.globalToLocal(drag.offset));
},
);
}
}

注意 renderBox.globalToLocal(drag.offset) 返回的偏移量是 Draggable 内部的偏移量(从开始位置到结束位置)。这就是为什么我们需要通过设置 _dragOffset += offset 来计算最终偏移量。

关于flutter - 为什么可拖动小部件没有放置在正确的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64114904/

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