如何以编程方式模拟 Flutter 中按钮上的 onTap?
How do I programmatically simulate onTap on a button in Flutter?
例如:
// Update: This GestureDetector is embedded inside a third party package
// that will invoke a series of animation along with the onTap button
GestureDetector(
onTap: () => print('Hey There!'),
child: Widget1(),
)
// Then another place in the same screen
GestureDetector(
onDoubleTap: () {
//Call the onTap of Widget1's GestureDetector
print('I'm Here');
}
child: Widget2(),
)
我想要的是当用户双击 Widget2
时,它还会调用 Widget1
的 onTap
回调。
更新:
所以我不想只调用传递到 Widget1
的 GestureDetector
的 onTap
的函数,而是以编程方式点击 Widget1 的 GestureDetector
[的 onTap
我该怎么做?
单独做第一个的功能就可以了
void firstFunction(){
print('hey There!');
}
像这样,然后在第二个widget中调用
所以您的代码将如下所示:
GestureDetector(
onTap: () => firstFunction(),
child: Widget1(),
)
// Then another place in the same screen
GestureDetector(
onDoubleTap: () {
firstFunction();
print('I'm Here');
}
child: Widget2(),
)
Update: So I do not want to just invoke a function passed into the onTap of GestureDetector of Widget1, but rather to programmatically tap the onTap of Widget1's GestureDetector
onTap的作用是调用onTap内部的回调函数。所以我不确定为什么你只想点击按钮而不是调用点击该按钮时应该调用的函数(你能详细说明一下吗?)。
如果你想模拟水龙头进行测试,你可以使用 Flutter Driver driver.tap()
你可以这样做 -
创建你的手势检测器 -
GestureDetector gestureDetector = GestureDetector(
onTap: () {
setState(() {
_lights = !_lights;
});
},
child: Container(
color: Colors.yellow.shade600,
padding: const EdgeInsets.all(8),
child: const Text('TURN LIGHTS ON'),
),
);
创建一个按钮(或您想要使用的任何小部件)以在 GestureDetector gestureDetector.onTap()
上调用 onTap
,就像在另一个小部件上调用方法一样。 (我这里用的是FlatButton
)-
FlatButton(
color: Colors.blue,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
onPressed: () {
//Trigger the GestureDetector onTap event.
gestureDetector.onTap();
},
child: Text("Click Here"),
),
现在您可以单击 FlatButton 来调用 GestureDetector 上的 onTap
事件。
这是完整的例子-
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Gesture Detector On Tap'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _lights = false;
@override
Widget build(BuildContext context) {
GestureDetector gestureDetector = GestureDetector(
onTap: () {
setState(() {
_lights = !_lights;
});
},
child: Container(
color: Colors.yellow.shade600,
padding: const EdgeInsets.all(8),
child: const Text('TURN LIGHTS ON'),
),
);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
alignment: FractionalOffset.center,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.lightbulb_outline,
color: _lights ? Colors.yellow.shade600 : Colors.black,
size: 60,
),
),
gestureDetector,
SizedBox(height: 50.0),
FlatButton(
color: Colors.blue,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
onPressed: () {
gestureDetector.onTap();
},
child: Text("Click Here"),
),
],
),
),
),
);
}
}
你会得到这样的东西-
在几次错误的开始之后,这对我有用。我使用 Riverpod,这个示例代码中的 formFocusIdProvider 是一个简单的 StateProvider。
我实际上不清楚为什么我需要添加延迟 - 但如果没有它,小部件重绘的行为是不可预测的。
此代码在构建方法中。
ref.listen(formFocusIdProvider, (previous, next) {
if (<some condition>) {
Future.delayed(const Duration(milliseconds: 200), () {
if (mounted) {
onTapFunction();
}
});
}
});
例如:
// Update: This GestureDetector is embedded inside a third party package
// that will invoke a series of animation along with the onTap button
GestureDetector(
onTap: () => print('Hey There!'),
child: Widget1(),
)
// Then another place in the same screen
GestureDetector(
onDoubleTap: () {
//Call the onTap of Widget1's GestureDetector
print('I'm Here');
}
child: Widget2(),
)
我想要的是当用户双击 Widget2
时,它还会调用 Widget1
的 onTap
回调。
更新:
所以我不想只调用传递到 Widget1
的 GestureDetector
的 onTap
的函数,而是以编程方式点击 Widget1 的 GestureDetector
[的 onTap
我该怎么做?
单独做第一个的功能就可以了
void firstFunction(){
print('hey There!');
}
像这样,然后在第二个widget中调用 所以您的代码将如下所示:
GestureDetector(
onTap: () => firstFunction(),
child: Widget1(),
)
// Then another place in the same screen
GestureDetector(
onDoubleTap: () {
firstFunction();
print('I'm Here');
}
child: Widget2(),
)
Update: So I do not want to just invoke a function passed into the onTap of GestureDetector of Widget1, but rather to programmatically tap the onTap of Widget1's GestureDetector
onTap的作用是调用onTap内部的回调函数。所以我不确定为什么你只想点击按钮而不是调用点击该按钮时应该调用的函数(你能详细说明一下吗?)。
如果你想模拟水龙头进行测试,你可以使用 Flutter Driver driver.tap()
你可以这样做 -
创建你的手势检测器 -
GestureDetector gestureDetector = GestureDetector(
onTap: () {
setState(() {
_lights = !_lights;
});
},
child: Container(
color: Colors.yellow.shade600,
padding: const EdgeInsets.all(8),
child: const Text('TURN LIGHTS ON'),
),
);
创建一个按钮(或您想要使用的任何小部件)以在 GestureDetector gestureDetector.onTap()
上调用 onTap
,就像在另一个小部件上调用方法一样。 (我这里用的是FlatButton
)-
FlatButton(
color: Colors.blue,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
onPressed: () {
//Trigger the GestureDetector onTap event.
gestureDetector.onTap();
},
child: Text("Click Here"),
),
现在您可以单击 FlatButton 来调用 GestureDetector 上的 onTap
事件。
这是完整的例子-
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Gesture Detector On Tap'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _lights = false;
@override
Widget build(BuildContext context) {
GestureDetector gestureDetector = GestureDetector(
onTap: () {
setState(() {
_lights = !_lights;
});
},
child: Container(
color: Colors.yellow.shade600,
padding: const EdgeInsets.all(8),
child: const Text('TURN LIGHTS ON'),
),
);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
alignment: FractionalOffset.center,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.lightbulb_outline,
color: _lights ? Colors.yellow.shade600 : Colors.black,
size: 60,
),
),
gestureDetector,
SizedBox(height: 50.0),
FlatButton(
color: Colors.blue,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
onPressed: () {
gestureDetector.onTap();
},
child: Text("Click Here"),
),
],
),
),
),
);
}
}
你会得到这样的东西-
在几次错误的开始之后,这对我有用。我使用 Riverpod,这个示例代码中的 formFocusIdProvider 是一个简单的 StateProvider。
我实际上不清楚为什么我需要添加延迟 - 但如果没有它,小部件重绘的行为是不可预测的。
此代码在构建方法中。
ref.listen(formFocusIdProvider, (previous, next) {
if (<some condition>) {
Future.delayed(const Duration(milliseconds: 200), () {
if (mounted) {
onTapFunction();
}
});
}
});