我有一个小部件按钮,单击时,飞溅在单击时无法正确显示,因为它直接进入路线并且速度非常快,是否可以给一个时间让点击动画被看到,然后按照路线?
Card(
margin: EdgeInsets.only(top: 20, left: 20, right: 20),
child: InkWell(onTap: () => Navigator.of(context).pushNamed('/textvoice'),
child: Text('hello')))
onTap: () async {
await Future.delayed(Duration(milliseconds: 600));
Navigator.of(context).pushNamed('/textvoice');
}
首先,创建一个布尔变量用于检查动画。
bool isLoading = false;
然后你可以尝试这个:
Card(
margin: EdgeInsets.only(top: 20, left: 20, right: 20),
child: InkWell(
onTap: () async {
setState(() => isLoading = true);
await Future.delayed(Duration(seconds: 2));
setState(() => isLoading = fasle);
Navigator.of(context).pushNamed('/textvoice');
},
child: Center(
child: isLoading ? CircularProgressIndicator() : Text('hello'),
),
),
);
如果你不确定理解这一点,我会给你完整的 Stateful Widget
import 'package:flutter/material.dart';
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool isLoading = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: buildButton(context),
),
);
}
Card buildButton(BuildContext context) {
return Card(
margin: EdgeInsets.only(top: 20, left: 20, right: 20),
child: InkWell(
onTap: () async {
setState(() => isLoading = true);
await Future.delayed(Duration(seconds: 2));
setState(() => isLoading = true);
Navigator.of(context).pushNamed('/textvoice');
},
child: Center(
child: isLoading ? CircularProgressIndicator() : Text('hello'),
),
),
);
}
}
为了避免多个不必要的手势(即用户不小心快速按下按钮两次导致 onTap 回调被调用两次,从而 Navigator 将 Route 推送到堆栈上两次),您应该使用布尔标志(例如 isTapped)。 例如:
@override
Widget build(BuildContext context) {
bool isTapped = false;
return ElevatedButton(
onPressed: () async {
if (!isTapped) {
isTapped = true;
await Future.delayed(const Duration(milliseconds: 160));
Navigator.of(context).pushNamed('/textvoice');
isTapped = false;
}
},
child: const Text('delayed splash effect')
);
}