有没有办法阻止手势在颤动中冒泡?

Nar*_*rek 10 tabbar gesturedetector dart flutter

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

当我尝试移动容器选项卡栏onHorizontalDragUpdate调用和选项卡栏更改选项卡而不是容器时。

如果我在 javascript 中像 stoppropagation 这样的容器上贴上胶带,有什么办法可以防止 onHorizo​​ntalDragUpdate 吗?

TabBarView(
        controller: _tabController,
        children: [
          Container(
            color: Colors.red,
          ),
          TabWithDragableContainer(),
          Container(
            color: Colors.blue,
          ),
        ],
      )
Run Code Online (Sandbox Code Playgroud)

Thi*_*rry 1

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

最小工作示例

在此输入图像描述

此示例有三个选项卡:

  1. 基本的Tab
  2. Draggable小部件的选项卡
  3. 带有 onPan 的选项卡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),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)