首页 > 解决方案 > GestureDetector 在 TabBarView 上不起作用

问题描述

我想检测 TabBarView 上的手势,所以我将 TabBarView 包装在 GestureDetector 小部件中,但它没有注册任何类型的手势。并且滑动到不同的标签有效。我只想检测手势。

TabController _tabController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(//I have 3 tabs in here at AppBar.bottum),

///This is where I need help with the GestureDetector not working.

      body: GestureDetector(
        onHorizontalDragStart: (DragStartDetails details) {
          print('Start : ');
          print(details);
        },
        child: TabBarView(controller: _tabController, children: <Widget>[
          Tab(icon: Icon(Icons.category)),
          Tab(icon: Icon(Icons.home)),
          Tab(icon: Icon(Icons.star)),
        ]),
      ),


    );
  }

标签: flutterflutter-layout

解决方案


嵌套手势小部件

您遇到此问题的原因是这两个小部件都接收触摸输入,并且当您有两个小部件接收触摸输入时,长话短说孩子会赢得这场战斗。这是长篇大论。因此,您的TabBarView和的两个输入GestureDetector都被发送到所谓的 a GestureArena。那里的竞技场考虑了多种不同的因素,但故事的结局是孩子总是赢。您可以通过定义自己的来解决此问题,RawGestureDetectorGestureFactory将改变竞技场的执行方式。

RawGestureDetector(
      gestures: {
        AllowMultipleGestureRecognizer: GestureRecognizerFactoryWithHandlers<
            AllowMultipleGestureRecognizer>(
          () => AllowMultipleGestureRecognizer(),
          (AllowMultipleGestureRecognizer instance) {
            instance.onTap = () => print('Episode 4 is best! (parent container) ');
          },
        )
      },
      behavior: HitTestBehavior.opaque,
      //Parent Container
      child: Container(
        color: Colors.blueAccent,
        child: Center(
          //Wraps the second container in RawGestureDetector
          child: RawGestureDetector(
            gestures: {
              AllowMultipleGestureRecognizer:
                  GestureRecognizerFactoryWithHandlers<
                      AllowMultipleGestureRecognizer>(
                () => AllowMultipleGestureRecognizer(),  //constructor
                (AllowMultipleGestureRecognizer instance) {  //initializer
                  instance.onTap = () => print('Episode 8 is best! (nested container)');
                },
              )
            },
            //Creates the nested container within the first.
            child: Container(
               color: Colors.yellowAccent,
               width: 300.0,
               height: 400.0,
            ),
          ),
        ),
      ),
    );


class AllowMultipleGestureRecognizer extends TapGestureRecognizer {
  @override
  void rejectGesture(int pointer) {
    acceptGesture(pointer);
  }
}

我想将所有功劳归功于Flutter Deep Dive: Gestures的作者 Nash,这是一篇很棒的文章,我强烈建议您查看。


推荐阅读