我正在使用缩放/平移手势。 我在本书中找到了部分合适的例子:
我基于它的代码:
Offset _startLastOffset = Offset.zero;
Offset _lastOffset = Offset.zero;
Offset _currentOffset = Offset.zero;
double _lastScale = 1.0;
double _currentScale = 1.0;
void _onScaleStart(ScaleStartDetails details) {
_startLastOffset = details.focalPoint;
_lastOffset = _currentOffset;
_lastScale = _currentScale;
}
void _onScaleUpdate(ScaleUpdateDetails details) {
if (details.scale != 1.0) {
// Scaling
double currentScale = _lastScale * details.scale;
if (currentScale < 0.5) {
currentScale = 0.5;
}
_currentScale = currentScale;
_bloc.setScale(_currentScale);
} else if (details.scale == 1.0) {
// We are not scaling but dragging around screen
// Calculate offset depending on current Image scaling.
Offset offsetAdjustedForScale = (_startLastOffset - _lastOffset) / _lastScale;
Offset currentOffset = details.focalPoint - (offsetAdjustedForScale * _currentScale);
_currentOffset = currentOffset;
_bloc.setOffset(_currentOffset);
}
}
---------------
child: StreamBuilder<Object>(
stream: _bloc.scale,
builder: (context, snapshot1) {
double _cscale = snapshot1.hasData? snapshot1.data : _currentScale;
return StreamBuilder<Object>(
stream: _bloc.offset,
builder: (context, snapshot2) {
Offset _coffset = snapshot2.hasData? snapshot2.data : _currentOffset;
return Transform(
transform: Matrix4.identity()
..scale(_cscale, _cscale)
..translate(_coffset.dx, _coffset.dy),
alignment: FractionalOffset.center,
child: Stack(
key: _imgStack,
fit: StackFit.expand,
children: <Widget>[
Image(image: AssetImage('assets/images/image.png')),
SvgPicture.asset(svgFile)
],
),
);
}
);
}
),
但是,缩放小部件时,其Pan的行为不自然-小部件在移动方向上的移动远比手指远。
我设法通过更改来解决此问题:
_currentOffset = currentOffset;
_bloc.setOffset(_currentOffset);
收件人:
_bloc.setOffset(currentOffset/_currentScale);
_currentOffset = currentOffset;
可以完全按预期工作,但是直到第二次缩放为止。 第二次缩放后,小部件在第一次触摸时发生移位。 放大时,它移到右边,缩小时,它移到左边。
有什么想法吗?
答案 0 :(得分:0)
使用InteractiveViewer
小部件。这是一个例子。
@override
Widget build(BuildContext context) {
return Center(
child: InteractiveViewer(
boundaryMargin: EdgeInsets.all(100),
minScale: 0.1,
maxScale: 1.5,
child: Container(width: 200, height: 200, color: Colors.blue),
),
);
}