gpt4 book ai didi

Flutter:如何为任何容器实现旋转和平移/移动手势?

转载 作者:IT王子 更新时间:2023-10-29 07:23:06 24 4
gpt4 key购买 nike

我已经为容器实现了缩放手势。另外,我添加了 onHorizo​​ntalDragUpdate 和 onVerticalDragUpdate。但是当我尝试同时添加两者时,我得到一个异常,提示无法使用 Scale 手势同时实现。即使对于 Pan 手势,它也会抛出相同的异常。下面是我的代码:

import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' hide Colors;
import 'dart: math' as math;

class HomeScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return HomeState();
}
}

class HomeState extends State<HomeScreen> {

double _scale = 1.0;
double _previousScale;
var yOffset = 400.0;
var xOffset = 50.0;
var rotation = 0.0;
var lastRotation = 0.0;

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: Stack(
children: <Widget>[
stackContainer(),
],
),
);
}

Widget stackContainer() {

return Stack(
children: <Widget>[
Positioned.fromRect(
rect: Rect.fromPoints( Offset(xOffset, yOffset),
Offset(xOffset+250.0, yOffset+100.0)),
child: GestureDetector(
onScaleStart: (scaleDetails) {
_previousScale = _scale;
print(' scaleStarts = ${scaleDetails.focalPoint}');
},
onScaleUpdate: (scaleUpdates){
//ScaleUpdateDetails
rotation += lastRotation - scaleUpdates.rotation;
lastRotation = scaleUpdates.rotation;
print("lastRotation = $lastRotation");
print(' scaleUpdates = ${scaleUpdates.scale} rotation = ${scaleUpdates.rotation}');
setState(() => _scale = _previousScale * scaleUpdates.scale);
},
onScaleEnd: (scaleEndDetails) {
_previousScale = null;
print(' scaleEnds = ${scaleEndDetails.velocity}');
},
child:
Transform(
transform: Matrix4.diagonal3( Vector3(_scale, _scale, _scale))..rotateZ(rotation * math.pi/180.0),
alignment: FractionalOffset.center,
child: Container(
color: Colors.red,
),
)
,
),
),
],
);
}
}

我想在红色 subview 周围移动并随着比例旋转。

最佳答案

scale相关事件中,除了缩放(缩放)之外,您还可以使用focalPoint来计算平移。还支持在缩放时平移。

演示:

pan and zoom demo

这是用于上述演示的代码:

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ZoomAndPanDemo(),
);
}
}

class ZoomAndPanDemo extends StatefulWidget {
@override
_ZoomAndPanDemoState createState() => _ZoomAndPanDemoState();
}

class _ZoomAndPanDemoState extends State<ZoomAndPanDemo> {
Offset _offset = Offset.zero;
Offset _initialFocalPoint = Offset.zero;
Offset _sessionOffset = Offset.zero;

double _scale = 1.0;
double _initialScale = 1.0;

@override
Widget build(BuildContext context) {
return GestureDetector(
onScaleStart: (details) {
_initialFocalPoint = details.focalPoint;
_initialScale = _scale;
},
onScaleUpdate: (details) {
setState(() {
_sessionOffset = details.focalPoint - _initialFocalPoint;
_scale = _initialScale * details.scale;
});
},
onScaleEnd: (details) {
setState(() {
_offset += _sessionOffset;
_sessionOffset = Offset.zero;
});
},
child: Transform.translate(
offset: _offset + _sessionOffset,
child: Transform.scale(
scale: _scale,
child: FlutterLogo(),
),
),
);
}
}

旁注:即使像 onHorizo​​ntalDragUpdate 这样的事件在与缩放相关的事件一起使用时不会导致运行时异常,但它们仍然会导致冲突并导致较差的用户体验。

还值得注意的是,InteractiveViewer 是一个内置的 Flutter 小部件,可以满足您的大部分需求,因此您可能不需要使用 GestureDetector完全转变

关于Flutter:如何为任何容器实现旋转和平移/移动手势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54536275/

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