美文网首页
flutter GestureDetector手势点击穿透分析

flutter GestureDetector手势点击穿透分析

作者: 小话001 | 来源:发表于2021-05-28 15:11 被阅读0次

    正常情况下,我们遇到这种嵌套的Container,有时候会发生点击穿透情况。


    01.jpg

    我发现当使用手势包裹的时候

    若调用onTap事件,则不会发生穿透现象,调用onTapDown则会发生

    就算是手势里面加了behavior: HitTestBehavior.opaque也无效

    import 'package:flutter/material.dart';
    void main() => runApp(new MyApp());
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          initialRoute: "/", 
          routes: {
            "/": (context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
          },
        );
      }
    }
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
              title: new Text(widget.title),
            ),
            body: new Center(
              child: new Column(
                children: <Widget>[
                  GestureDetector(
                    // onTapDown: (detail){
                    //   print('outer click');
                    // },
                    onTap: () {
                       // 调用onTap 很多次是不会发生穿透现象的
                      print('outer click');
                    },
                    child: Container(
                      width: 200,
                      height: 200,
                      color: Colors.yellow,
                      alignment: Alignment.center,
                      child: GestureDetector(
                          onTap: () {
                            // 调用onTap 很多次是不会发生穿透现象的
                            print('inner click');
                          },
                          // onTapDown: (detail){
                          //   print('inner click');
                          // },
                          child: Container(width: 100, height: 100, color: Colors.red)),
                    ),
                  )
                ],
              ),
            ));
      }
    }
    
    解决方案:

    方案A:直接如代码所示使用onTap事件替代onTapDown事件;
    方案B:更换结构,两个容器不用嵌套的方式,改为Stack包裹布局

    import 'package:flutter/material.dart';
    void main() => runApp(new MyApp());
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          initialRoute: "/", 
          routes: {
            "/": (context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
          },
        );
      }
    }
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
              title: new Text(widget.title),
            ),
            body: new Center(
              child: new Column(
                children: <Widget>[
                  Text('测试'),
                  Stack(  
                    alignment: Alignment.center,
                    children: <Widget>[
                      GestureDetector(
                      onTapDown: (detail){
                        print('outer click');
                      },
                      child: Container(
                        width: 200,
                        height: 200,
                        color: Colors.yellow,
                        alignment: Alignment.center,
                      ),
                     ),
                      GestureDetector(
                            onTapDown: (detail){
                              print('inner click');
                            },
                            child: Container(width: 100, height: 100, color: Colors.red))
                    ],
                  )
                  ]
              ),
            ));
      }
    }
    

    如果点击黄颜色外层区域,而不想触发里面的红颜色区域,则可直接在红颜色区域GestureDetector外面再套一层

    IgnorePointer(
          child: GestureDetector(
             onTapDown: (detail){print('inner click');},
             child: Container(width: 100, height: 100, color: Colors.red)),
    )
    

    相关文章

      网友评论

          本文标题:flutter GestureDetector手势点击穿透分析

          本文链接:https://www.haomeiwen.com/subject/masssltx.html