Ich denke, Flutter Pan Gestenerkenner sollte wahrscheinlich auf die Skala Gestenerkenner ergeben, wenn es erkennt, dass ein zweiter Zeiger ist unten und eine Skala Geste Erkennung ist aktiv. Fühlen Sie sich frei, ein Problem dafür zu melden, wenn Sie zustimmen.
In der Zwischenzeit können Sie den Pan Gestenerkenner PageView
deaktivieren, indem Sie einen undurchsichtigen GestureRecognizer
darauf setzen und die Skalierungsereignisse an Ihren Status weiterleiten.
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,
),
);
}
}
Handhabung der Skala Gesten außerhalb der TabBarView
kann auch den skalierte Zustand der Registerkarten, anstatt sie, wenn auf 1,0 zurückgesetzt zu erinnern, verwendet werden, wenn sie außerhalb des Bildschirms ist.
Vielen Dank für Ihre Antwort! Ich habe heute früh ein Problem eingereicht, bin aber erst jetzt dazu gekommen, Ihre aktuelle Lösung auszuprobieren. Nur um sicher zu gehen: Dadurch wird die Swiping-Funktionalität der 'TabBarView' vollständig deaktiviert, sodass ich nur durch Klicken auf die' TabBar' Tabs wechseln kann, richtig? Gibt es eine Möglichkeit, Drag-Events an die TabBarView zu "weiterleiten", um sie zum Swipen zu verwenden? –
Vielen Dank für die Einreichung des Problems. Ich weiß leider nicht, wie man die Drag-Events an die TabBarView weiterleiten kann. Wenn dies für Sie wichtig ist, sehen wir, welche Antwort Sie auf das Problem bekommen. –
Hier ist das Problem, das David eingereicht hat, falls jemand anderes es befolgen möchte: https://github.com/flutter/flutter/issues/9949 –