我有一个 TabBarView
,其中每个选项卡都包含一个 Image
包装在 GestureDetector
中,用于缩放和平移。如果它很重要,这就是我目前实现缩放的方式:How do I pan and zoom an image? .
现在我遇到的问题是缩放仅在捏合移动非常垂直时才有效。如果我有点偏离,触摸事件会立即用于滑动到下一个选项卡,即使我正在使用两个手指。而且我认为水平平移根本行不通。
Flutter 中是否有任何机制允许内部 GestureDetector
在将它们馈送到 TabBarView
之前拦截某些触摸事件(但不是其他事件,而且并非总是如此)?
最佳答案
如果 Flutter 的平移手势识别器检测到第二个指针向下并且缩放手势识别器处于事件状态,我认为它可能应该让步于缩放手势识别器。如果您同意,请随时为此提出问题。
与此同时,您可以通过在其顶部放置一个不透明的 GestureRecognizer
并将缩放事件转发到您的状态来“禁用”PageView
的平移手势识别器.
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new DefaultTabController(
length: 2,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: [
new Tab(text: 'foo'),
new Tab(text: 'bar'),
],
),
),
body: new ScalableTabBarView()
),
);
}
}
class ScalableTabBarView extends StatelessWidget {
final List<GlobalKey<ScaledState>> keys = <GlobalKey<ScaledState>>[
new GlobalKey<ScaledState>(),
new GlobalKey<ScaledState>(),
];
Widget build(BuildContext context) {
return new Stack(children: [
new TabBarView(
children: [
new Center(
child: new Scaled(
child: new FlutterLogo(),
key: keys[0],
),
),
new Center(
child: new Scaled(
child: new FlutterLogo(),
key: keys[1],
),
),
],
),
new GestureDetector(
behavior: HitTestBehavior.opaque,
onScaleStart: (ScaleStartDetails details) {
keys[DefaultTabController.of(context).index].currentState.onScaleStart(details);
},
onScaleUpdate: (ScaleUpdateDetails details) {
keys[DefaultTabController.of(context).index].currentState.onScaleUpdate(details);
},
onScaleEnd: (ScaleEndDetails details)
{
keys[DefaultTabController.of(context).index].currentState.onScaleEnd(details);
}
),
],
);
}
}
class Scaled extends StatefulWidget {
Scaled({ Key key, this.child }) : super(key: key);
final Widget child;
State createState() => new ScaledState();
}
class ScaledState extends State<Scaled> {
double _previousScale;
double _scale = 1.0;
void onScaleStart(ScaleStartDetails details) {
print(details);
setState(() {
_previousScale = _scale;
});
}
void onScaleUpdate(ScaleUpdateDetails details) {
print(details);
setState(() {
_scale = _previousScale * details.scale;
});
}
void onScaleEnd(ScaleEndDetails details) {
print(details);
setState(() {
_previousScale = null;
});
}
@override
Widget build(BuildContext context) {
return new GestureDetector(
child: new Transform(
transform: new Matrix4.diagonal3(new Vector3(_scale, _scale, _scale)),
alignment: FractionalOffset.center,
child: widget.child,
),
);
}
}
在 TabBarView
之外处理缩放手势也可用于记住选项卡的缩放状态,而不是在它们离开屏幕时将它们重置为 1.0。
https://stackoverflow.com/questions/43869027/