当窗口小部件包装在InteractiveViewer中时,Flutter onPanStart会延迟调用 [英] Flutter onPanStart invokes late when the widget is wrapped inside InteractiveViewer
问题描述
我只是有一个简单的容器,该容器的右中间具有调整大小的手柄,这意味着可以使用该手柄调整容器的大小.它包装在 InteractiveViewer
小部件中.
I just have a simple container which has a resize handle on center right which means the container can be resized using that handle. It is wrapped inside InteractiveViewer
widget.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double _width = 300;
double _height = 200;
@override
Widget build(BuildContext context) {
final m = MediaQuery.of(context);
return Scaffold(
body: SafeArea(
child: Container(
height: m.size.height,
width: m.size.width,
child: InteractiveViewer(
maxScale: 30,
child: Stack(
children: <Widget>[
Container(height: _height, width: _width, color: Colors.red),
Positioned(
top: _height / 2 - 10,
left: _width - 20,
child: GestureDetector(
onPanStart: (details) {
print("PAN STARTED");
},
onPanUpdate: (details) {
final delta = details.delta;
setState(() {
_width = _width + delta.dx;
});
},
child: Container(height: 20, width: 20, color: Colors.blue),
),
)
],
),
),
),
),
);
}
}
问题是 onPanStart
在初始拖动后很晚才调用.任何帮助将不胜感激.
The problem is onPanStart
invokes a lot late after the initial drag. Any help would be greatly appreciated.
注意:此问题无法在DartPad中复制.在DartPad中,它可以正常工作.该问题只能在模拟器/电话中看到.
Note: This problem cannot be replicated in DartPad. In DartPad it works fine. The problem can only be seen in simulators/phones.
推荐答案
我找到了解决此问题的方法.只需使用Listener而不是GestureDetector(它可以替代大多数参数:onPanStart-> onPointerDown,onPanUpdate-> onPointerMove).有了Listener,就不会有延迟.
I found a fix for this issue. Just use Listener instead of GestureDetector (it has substitutes for the most parameters: onPanStart -> onPointerDown, onPanUpdate -> onPointerMove). With Listener, there will be no delay.
最小代码示例:
import 'package:flutter/material.dart';
class IssueExamplePage extends StatefulWidget {
@override
_IssueExamplePageState createState() => _IssueExamplePageState();
}
class _IssueExamplePageState extends State<IssueExamplePage> {
bool drawingBlocked = false;
List<Offset> points;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: InteractiveViewer(
child: AbsorbPointer(
absorbing: drawingBlocked,
child: Listener(
onPointerMove: (details) {
RenderBox renderBox = context.findRenderObject();
Offset cursorLocation = renderBox.globalToLocal(details.localPosition);
setState(() {
points = List.of(points)..add(cursorLocation);
});
},
child: CustomPaint(
painter: MyPainter(points),
size: Size.infinite
),
),
),
),
),
),
floatingActionButton: Column(
children: [
FloatingActionButton(
child: Icon(Icons.clear),
onPressed: () {
setState(() {
points = [];
});
}
),
FloatingActionButton(
child: Icon(drawingBlocked? CupertinoIcons.hand_raised_fill : CupertinoIcons.hand_raised),
onPressed: () {
drawingBlocked = !drawingBlocked;
}
),
],
),
);
}
}
class MyPainter extends CustomPainter {
MyPainter(this.points);
List<Offset> points;
Paint paintBrush = Paint()
..color = Colors.blue
..strokeWidth = 5
..strokeJoin = StrokeJoin.round;
@override
void paint(Canvas canvas, Size size) {
for (int i = 0; i < points.length - 1; i++) {
canvas.drawLine(points[i], points[i + 1], paintBrush);
}
}
@override
bool shouldRepaint(MyPainter oldDelegate) {
return points != oldDelegate.points;
}
}
这篇关于当窗口小部件包装在InteractiveViewer中时,Flutter onPanStart会延迟调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!