多次单击按钮,多次打开页面。如何解决这个问题?我还将gif文件上传到了我的应用程序中(双击图像)。
Container(
padding: EdgeInsets.all(10.0),
child: ButtonTheme(
minWidth: 10.0,
height: 40.0,
child: RaisedButton(
child: Text(
AppTranslations.of(context)
.text("loginpage_button"),
style: TextStyle(
color: Colors.white, fontSize: 15.0),
),
onPressed: () async{
(isOffline)
? _showSnackBar()
: checking2(usernameController, context, _url);
},
color: Colors.blue,
padding: EdgeInsets.all(20.0),
),
),
margin: EdgeInsets.only(top: 0.0),
)
我使用了此代码,它可以正常工作,但是用户输入的用户名错误,用户无法单击按钮的第二种类型。这是我的代码。
onPressed: () async {
if (_firstClick) {
_firstClick = false;
(isOffline)
? _showSnackBar()
: checking2(usernameController, context, _url);
}
答案 0 :(得分:1)
我为自己写了两节课,可能对其他人有帮助。它们将其他人给出的答案封装在该线程中,这样您就不会到处都是笨蛋和赋值语句。
将函数传递给类,然后使用类的“调用”方法代替函数。目前,该功能不支持需要参数的功能,但对于无效情况很有用。
typedef void CallOnceFunction();
class CallOnce {
bool _inFunction = false;
final CallOnceFunction function;
CallOnce(CallOnceFunction function) :
assert(function != null),
function = function
;
void invoke() {
if (_inFunction)
return;
_inFunction = true;
function();
_inFunction = false;
}
}
typedef Future<void> CallOnceFuture();
class CallFutureOnce {
bool _inFunction = false;
final CallOnceFuture future;
CallFutureOnce(CallOnceFuture future) :
assert(future != null),
future = future
;
Future<void> invoke() async {
if (_inFunction)
return;
_inFunction = true;
await this.future();
_inFunction = false;
}
}
更新:这是这两个类的实际示例
/*Example*/
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyWidgetState();
}
}
class MyWidgetState extends State<MyWidget> {
CallOnce _callOnce;
CallFutureOnce _callFutureOnce;
void myFunction() {
/*Custom Code*/
}
Future<void> myFutureFunction() async {
/*Custom Code*/
//await something()
}
@override
void initState() {
super.initState();
this._callOnce = CallOnce(this.myFunction);
this._callFutureOnce = CallFutureOnce(this.myFutureFunction);
}
@override
Widget build(BuildContext context) {
return Scaffold (
body: Center (
child: RaisedButton (
child: Text('Try Me'),
onPressed: this._callOnce.invoke,
),
),
floatingActionButton: FloatingActionButton (
child: Icon(Icons.save),
onPressed: this._callFutureOnce.invoke,
),
);
}
}
答案 1 :(得分:1)
基于计算时差在我的应用程序中解决了这个问题。
首先,声明一个DateTime变量并按如下所示定义函数:-
DateTime loginClickTime;
bool isRedundentClick(DateTime currentTime){
if(loginClickTime==null){
loginClickTime = currentTime;
print("first click");
return false;
}
print('diff is ${currentTime.difference(loginClickTime).inSeconds}');
if(currentTime.difference(loginClickTime).inSeconds<10){//set this difference time in seconds
return true;
}
loginClickTime = currentTime;
return false;
}
在登录按钮中,按如下所示调用函数以检查冗余:-
RaisedButton(
child:Text('Login'),
onPressed: (){
if(isRedundentClick(DateTime.now())){
print('hold on, processing');
return;
}
print('run process');
},
)
答案 2 :(得分:0)
您可以使用bool
变量来保存RaisedButton
的状态:
首先创建变量并为其设置初始值:
var _firstPress = true ;
然后在_firstPress
函数内添加onPressed
:
Container(
padding: EdgeInsets.all(10.0),
child: ButtonTheme(
minWidth: 10.0,
height: 40.0,
child: RaisedButton(
child: Text(
AppTranslations.of(context)
.text("loginpage_button"),
style: TextStyle(
color: Colors.white, fontSize: 15.0),
),
onPressed: () async{
// This is what you should add in your code
if(_firstPress){
_firstPress = false ;
(isOffline) ? _showSnackBar() :checking2(usernameController, context, _url);
}
},
color: Colors.blue,
padding: EdgeInsets.all(20.0),
),
),
margin: EdgeInsets.only(top: 0.0),
)
这样,您的onPressed
函数将只响应RaisedButton
的第一次单击。
答案 3 :(得分:0)
在这里How do I disable a Button in Flutter?
回答了这个问题所有您需要使用statefulWidget并创建一个变量来保存您的条件,并根据您的事件对其进行更改。您的按钮将根据变量的值启用或禁用。
假设变量的初始状态isDisable = false,这意味着-默认情况下您的按钮处于启用状态。在第一次单击更改后,您的状态变量的值为isDisable = true。
答案 4 :(得分:0)
您可以将其变成StatefulWidget,而不是直接使用RaisedButton。然后使用ChangeNotifier将其状态从启用更改为禁用并控制按钮按下功能,这还将帮助您在不同位置重用它。这是一个示例,您如何做到这一点
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ValueNotifier<MyButtonState> _myButtonStateChangeNotifier =
ValueNotifier(MyButtonState.enable);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: MyButton(
buttonStateChangeNotifier: _myButtonStateChangeNotifier,
onPressed: _onButtonPressed,
text: "Click Me",
),
),
);
}
_onButtonPressed() {
print("Button Pressed");
_myButtonStateChangeNotifier.value = MyButtonState.disable;
}
}
enum MyButtonState {enable, disable}
class MyButton extends StatefulWidget {
final VoidCallback onPressed;
final String text;
final TextStyle textStyle;
final ValueNotifier<MyButtonState> buttonStateChangeNotifier;
MyButton({
@required this.onPressed,
this.text = "",
this.textStyle,
this.buttonStateChangeNotifier,
});
@override
_MyButtonState createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
MyButtonState _myButtonState = MyButtonState.enable;
@override
void initState() {
super.initState();
if (widget.buttonStateChangeNotifier != null) {
widget.buttonStateChangeNotifier.addListener(_handleButtonStateChange);
_myButtonState = widget.buttonStateChangeNotifier.value;
}
}
@override
Widget build(BuildContext context) {
return RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(widget.text)
],
),
onPressed: _myButtonState == MyButtonState.enable
? _handleOnPress
: null,
);
}
_handleButtonStateChange() {
setState(() {
_myButtonState = widget.buttonStateChangeNotifier.value;
});
}
_handleOnPress() {
if (_myButtonState == MyButtonState.enable) {
widget.onPressed();
}
}
}
答案 5 :(得分:0)
感谢上面的@Mazin Ibrahim's建议,设置基本的bool
切换标记即可正常工作。
此实现基于在回调级别处理启用/禁用逻辑,而与小部件布局细节无关。
bool _isButtonEnabled = true;
MessageSql _messageSql = new MessageSql(); // DB helper class
final TextEditingController eCtrl = new TextEditingController();
_onSendMessage(String message) {
if (! _isButtonEnabled) {
return;
}
_isButtonEnabled = false;
_messageSql.insert(message).then((resultId) {
// only update all if save is successful
eCtrl.clear();
AppUi.dismissKeyboard();
_isButtonEnabled = true;
Future.delayed(const Duration(milliseconds: 400), () {
setState(() {});
})
.catchError((error, stackTrace) {
print("outer: $error");
});
}
答案 6 :(得分:0)
创建一个bool
变量,当按下按钮时它将为true
(因此,初始值设置为false
)。
bool _clicked = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: RaisedButton(
child: Text('Button'),
onPressed: _clicked
? null
: () {
setState(() => _clicked = true); // set it to true now
},
),
);
}