Flutter 如何忽略某个GestureDetector小部件的触碰,并在颤振中检测外部触碰?

Flutter 如何忽略某个GestureDetector小部件的触碰,并在颤振中检测外部触碰?,flutter,gesturedetector,flutter-animation,Flutter,Gesturedetector,Flutter Animation,我创建了一个下拉小部件,但当我触摸文本小部件或其内部的自由空间时,下拉高度会跳到触摸位置。如何忽略这种接触? 我使用了IgnorePointer小部件,但它也禁用了Switch小部件。 此外,如何检测外部触摸以关闭下拉窗口小部件 import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:movie_god/MyAp

我创建了一个下拉小部件,但当我触摸文本小部件或其内部的自由空间时,下拉高度会跳到触摸位置。如何忽略这种接触? 我使用了
IgnorePointer
小部件,但它也禁用了
Switch
小部件。 此外,如何检测外部触摸以关闭下拉窗口小部件

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:movie_god/MyApp.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp>{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter!'),
        ),
        body: Stack(
          children: <Widget>[
            Container(
              color: Colors.blueGrey[200],
              child: Center(
                child: Text('Widgets'),
              ),
            ),
            BottomFilter()
          ],
        ),
      ),
    );
  }

}

class BottomFilter extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => BottomFilterState();
}

class BottomFilterState extends State<BottomFilter> with SingleTickerProviderStateMixin{
  double _minHeight = 20;
  double _height;
  double _maxHeight = 200;
  double _transparentHeight = 30;
  AnimationController _controller;
  Animation _animation;
  Map<String,dynamic> _switches = {
    'switch1' : false,
    'switch2' : false,
    'switch3' : false,
    'switch4' : false,
    'option' : null
  };
  List<String> _options = <String>[];

  @override
  void initState() {
    _controller = AnimationController(vsync: this,duration: Duration(milliseconds: 500));
    _animation = Tween(begin: _minHeight+_transparentHeight, end: _maxHeight).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    Size _size = MediaQuery.of(context).size;

    return GestureDetector(
      onVerticalDragUpdate: (drag){
        setState(() {
          _controller.reset();
          double _postion = drag.globalPosition.dy-kToolbarHeight-_minHeight-_transparentHeight;
          print(_postion.toString());
          if(_postion<0){
            _height=_minHeight+_transparentHeight;
          } else if(_postion>_maxHeight){
            double _newHeight = _maxHeight+_transparentHeight+_minHeight + ((_size.height-_postion)/_size.height)*((_postion-_maxHeight));
            _height < _newHeight ? _height = _newHeight: null;
          } else{
            _height = _postion+_transparentHeight+_minHeight;
          }
          _animation = Tween(begin: _height, end: _maxHeight).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut));
        });
      },
      onVerticalDragEnd: (drag){
        if(_height>_maxHeight || _height>=_maxHeight/2){
          _animation = Tween(begin: _height, end: _maxHeight).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut));
          _controller.forward();
        }else if(_height<_maxHeight/2){
          _animation = Tween(begin: _height, end: _minHeight+_transparentHeight).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut));
          _controller.forward();
        }
      },
      child: AnimatedBuilder(
        animation: _controller,
        builder: (context,Widget child){
          return Stack(
            children: <Widget>[
              Positioned(
                bottom: _size.height - (kToolbarHeight + 20 + _animation.value),
                child: child,
              )
            ],
          );
        },
        child: Container(
            height: 400,
            width: _size.width,
            color: Colors.transparent,
            child: Padding(
              padding: EdgeInsets.only(bottom: _transparentHeight),
              child: Container(
                height: 300,
                alignment: Alignment.bottomCenter,
                width: _size.width,
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.vertical(bottom: Radius.circular(20))
                ),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Text('switch1',style: TextStyle(color: Colors.blueGrey[800]),),
                        Switch.adaptive(
                          inactiveThumbColor: Colors.blue,
                          value: _switches['switch1'],
                          onChanged: (value){
                            setState(() {
                              _switches['switch1'] = value;
                            });
                          },
                        ),
                        Text('switch2',style: TextStyle(color: Colors.blueGrey[800]),),
                        Switch.adaptive(
                          value: _switches['switch2'],
                          onChanged: (value){
                            setState(() {
                              _switches['switch2'] = value;
                            });
                          },
                        ),
                        Text('switch3',style: TextStyle(color: Colors.blueGrey[800]),),
                        Switch.adaptive(
                          value: _switches['switch3'],
                          onChanged: (value){
                            setState(() {
                              _switches['switch3'] = value;
                            });
                          },
                        ),
                      ],
                    ),
                    Row(
                      mainAxisSize: MainAxisSize.min,
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Theme(
                          data: Theme.of(context).copyWith(
                              canvasColor: Colors.white,
                              brightness: Brightness.light
                          ),
                          child: Row(
                            children: <Widget>[
                              DropdownButton<String>(
                                value: _switches['option'],
                                hint: Text('sample1',style: TextStyle(color: Colors.blueGrey[800]),),
                                style: TextStyle(
                                    color: Colors.blueGrey[800]
                                ),
                                onChanged: (String value){
                                  if(value != null){
                                    setState(() {
                                      _switches['option'] = value;
                                      print(_switches['option']);
                                    });
                                  }
                                },
                                items: <String>['option1','option2','option3','option4','option5','option6'].map<DropdownMenuItem<String>>((value){
                                  return DropdownMenuItem<String>(
                                      value: value,
                                      child : Align(child: Text(value),alignment: Alignment(1, 0),)
                                  );
                                }).toList(),
                              ),
                            ],
                          ),
                        ),
                        Theme(
                          data: Theme.of(context).copyWith(
                              canvasColor: Colors.white,
                              brightness: Brightness.light
                          ),
                          child: Row(
                            children: <Widget>[
                              DropdownButton<String>(
                                hint: Text('sample2',style: TextStyle(color: Colors.blueGrey[800]),),
                                style: TextStyle(
                                    color: Colors.blueGrey[800]
                                ),
                                onChanged: (String value){
                                  if(value != null){
                                    _options.indexOf(value)<0?
                                    setState(() {
                                      _options.add(value);
                                    }) : null;
                                  }
                                },
                                items: <String>['option1','option2','option3','option4','option5','option6'].map<DropdownMenuItem<String>>((value){
                                  return DropdownMenuItem<String>(
                                      value: value,
                                      child : Align(child: Text(value),alignment: Alignment(1, 0),)
                                  );
                                }).toList(),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 50,
                      child: ListView(
                        shrinkWrap: false,
                        scrollDirection: Axis.horizontal,
                        children: _genresGenerator(),
                      ),
                    ),
                    Align(
                      alignment: Alignment.bottomCenter,
                      child: Column(
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.symmetric(horizontal: 40),
                            child: Divider(
                              color: Colors.blueGrey[500],
                              height: 10,
                              indent: 5,
                            ),
                          ),
                          Icon(FontAwesomeIcons.angleDoubleDown,size: 15,color: Colors.blueGrey[500],)
                        ],
                      ),
                    )
                  ],
                ),
              ),
            )
        ),
      ),
    );

  }

  List<Widget> _genresGenerator() {
    List<Widget> _optionsWidgets = _options.map<Widget>((String name) {
      return InputChip(
          key: ValueKey<String>(name),
          label: Text(name),
          onDeleted: () {
            setState(() {
              _removeTool(name);
            });
          });
    }).toList();

    return _optionsWidgets;
  }

  void _removeTool(String name) {
    _options.remove(name);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

}
导入“包装:颤振/材料.省道”;
导入“package:font_awesome_flatter/font_awesome_flatter.dart”;
导入“包:movie_god/MyApp.dart”;
void main()=>runApp(MyApp());
类MyApp扩展了StatefulWidget{
@凌驾
State createState()=>MyAppState();
}
类MyAppState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
appBar:appBar(
标题:文本('flatter!'),
),
主体:堆栈(
儿童:[
容器(
颜色:颜色。蓝灰色[200],
儿童:中心(
子:文本('Widgets'),
),
),
底部过滤器()
],
),
),
);
}
}
类BottomFilter扩展了StatefulWidget{
@凌驾
状态createState()=>BottomFilterState();
}
类BottomFilterState使用SingleTickerProviderStateMixin扩展状态{
双倍最小高度=20;
双倍高度;
双倍最大高度=200;
双透明光=30;
动画控制器_控制器;
动画(动画),;
映射开关={
“开关1”:错误,
“开关2”:错误,
“开关3”:错误,
“开关4”:错误,
“选项”:null
};
列表_选项=[];
@凌驾
void initState(){
_controller=AnimationController(vsync:this,duration:duration(毫秒:500));
_动画=Tween(开始:_minHeight+_transparentHeight,结束:_maxHeight)。动画(曲线动画(父级:_控制器,曲线:Curves.easeOut));
super.initState();
}
@凌驾
小部件构建(构建上下文){
Size _Size=MediaQuery.of(context).Size;
返回手势检测器(
onVerticalDragUpdate:(拖动){
设置状态(){
_controller.reset();
double _position=drag.globalPosition.dy-kToolbarHeight--u minHeight--u transparentHeight;
打印(_position.toString());
如果(\u位置\u最大高度){
double _newHeight=_maxHeight+_transparentHeight+_minHeight+((_size.height-_position)/_size.height)*((_position-_maxHeight));
_高度<\u新高度?\u高度=\u新高度:空;
}否则{
_高度=_位置+_透明度光+_最小高度;
}
_animation=Tween(开始:_height,结束:_maxHeight)。设置动画(CurvedAnimation(父级:_控制器,曲线:Curves.easeOut));
});
},
垂直排水量:(阻力){
如果(_height>_maxHeight ||_height>=_maxHeight/2){
_animation=Tween(开始:_height,结束:_maxHeight)。设置动画(CurvedAnimation(父级:_控制器,曲线:Curves.easeOut));
_controller.forward();
}否则,如果(_)高度可能重复