GestureDetector in TabBarView - nested scroll?

I have TabBarViewwhere each tab contains Image, wrapped in GestureDetectorfor zooming and panning. If that matters, thatโ€™s how I implement scaling: How do I copy and enlarge an image? .

Now I have a problem that scaling only works when the clamp movement is very vertical. If I'm a little bigger, touch events are immediately used to go to the next tab, although I use both fingers. And I believe that horizontal panning will not work at all.

Is there any mechanism in Flutter that allows the inside to GestureDetectorintercept certain touch events (but not others, but not always) before serving them on TabBarView?

+4
source share
1 answer

I think that the Flutter pan gesture recognizer should probably go to the scale gesture recognizer if it detects that the second pointer is omitted and the scale recognition flag is active. If you agree, write about it.

In the meantime, you can โ€œturn offโ€ the gesture recognizer by PageViewplacing an opaque GestureRecognizeron top of it and redirecting scale events to your state.

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 , reset 1.0, .

+4

Source: https://habr.com/ru/post/1676743/


All Articles