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();
}否则,如果(_)高度可能重复