有什么方法可以阻止手势颤抖吗?

时间:2019-10-27 20:53:46

标签: flutter dart tabbar gesturedetector

我有3个孩子的TabBarView,其中一个我有一个带有onPanUpdate手势的容器。

当我尝试移动容器标签栏onHorizontalDragUpdate调用时,标签栏会更改标签,但不会更改容器。

如果我像JavaScript中的stoppropagation一样在容器上录音,有什么方法可以防止onHorizo​​ntalDragUpdate吗?

TabBarView(
        controller: _tabController,
        children: [
          Container(
            color: Colors.red,
          ),
          TabWithDragableContainer(),
          Container(
            color: Colors.blue,
          ),
        ],
      )

1 个答案:

答案 0 :(得分:1)

您可以通过在 TabBarView 中指定 physics: NeverScrollableScrollPhysics() 来禁用所有选项卡的手势。

最小工作示例

enter image description here

这个例子有三个标签:

  1. 基本Tab
  2. 带有 Draggable 小部件的标签
  3. 带有 onPan 的 Tab GestureDetector
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            tabs: [
              Tab(icon: Icon(Icons.directions_car)),
              Tab(icon: Icon(Icons.directions_transit)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(
          physics: NeverScrollableScrollPhysics(),
          children: [
            Icon(Icons.directions_car),
            _ContainerWithDraggable(),
            _ContainerWithPanGesture(),
          ],
        ),
      ),
    );
  }
}

class _ContainerWithDraggable extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _offset = useState(Offset(100, 100));
    return Stack(
      children: [
        Container(color: Colors.amber.shade100),
        Positioned(
          top: _offset.value.dy,
          left: _offset.value.dx,
          child: Draggable(
            onDragUpdate: (details) => _offset.value += details.delta,
            feedback: _Circle(),
            child: _Circle(),
          ),
        ),
      ],
    );
  }
}

class _ContainerWithPanGesture extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _offset = useState(Offset(100, 100));
    final _previousOffset = useState<Offset>(null);
    final _referenceOffset = useState<Offset>(null);
    return Stack(
      children: [
        GestureDetector(
          onPanStart: (details) {
            _previousOffset.value = _offset.value;
            _referenceOffset.value = details.localPosition;
          },
          onPanUpdate: (details) => _offset.value = _previousOffset.value +
              details.localPosition -
              _referenceOffset.value,
          child: Container(color: Colors.amber.shade100),
        ),
        Positioned(
          top: _offset.value.dy,
          left: _offset.value.dx,
          child: _Circle(),
        ),
      ],
    );
  }
}

class _Circle extends StatelessWidget {
  const _Circle({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 50,
      height: 50,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        border: Border.all(color: Colors.brown, width: 5.0),
      ),
    );
  }
}