英文:
Disable / change the color of a button for a certain seconds if it was clicked
问题
我有一个问题。我想在用户点击按钮后禁用按钮3秒钟。3秒后用户应该能够再次点击按钮。
我创建了一个变量 _hasBeenPressed
。但问题是我的输出不是我希望的。
什么都没有发生。如果我点击按钮,按钮的颜色没有改变。
那么,如果按钮被按下,如何在3秒内更改按钮的颜色并在此期间禁用 onTap
?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../utils/definitions.dart';
import 'icons.dart';
import '../model/label.dart';
class LabelButton extends StatefulWidget {
final Label? label;
final VoidStringCallback? process;
LabelButton({required this.label, required this.process, Key? key})
: super(key: key);
@override
State<LabelButton> createState() => _LabelButtonState();
const LabelButton._(this.label, this.process, {Key? key})
: super(key: key);
static LabelButton createBlank() {
return const LabelButton._(null, null);
}
}
class _LabelButtonState extends State<LabelButton> {
bool _hasBeenPressed = false;
@override
Widget build(BuildContext context) {
if (widget.label != null) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Material(
child: InkWell(
highlightColor: Color(0xFF00D3F8).withOpacity(0.3),
splashColor: Color(0xFFB20DD3).withOpacity(0.3),
onTap: () {
setState(() async {
_hasBeenPressed = true;
print("CLICKED");
await Future.delayed(const Duration(seconds: 3), () {
print("nach");
_hasBeenPressed = false;
});
print(_hasBeenPressed);
});
widget.process!(widget.label!.identifier, widget.label!.category, widget.label!.id);
HapticFeedback.lightImpact();
},
child: Ink(
width: 100,
height: 120,
decoration: BoxDecoration(
color: _hasBeenPressed ? const Color(0xFFB6B6B6) : Colors.green,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(iconList
.firstWhere((element) => element.name == widget.label!.uiIcon)
.icon,
size: 80,),
Text(widget.label!.categoryName,
style: const TextStyle(
color: Color(0xFF696969),
)),
Text(widget.label!.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
)),
],
),
),
),
)
)
);
}
else {
return Container();
}
}
}
英文:
I have a problem. I want to disable the button for 3 seconds if the user clicked on it. After 3 seconds the user should be able to click the button agian.
I created a variable _hasBeenPressed
. But the problem is that my output is not what I wished.
It does nothing happend. If I click the button the color of the button did not changed.
So how could I change the color of the button for 3 seconds if the button is pressed and disable the onTap also for the peroid of time?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../utils/definitions.dart';
import 'icons.dart';
import '../model/label.dart';
class LabelButton extends StatefulWidget {
final Label? label;
final VoidStringCallback? process;
LabelButton({required this.label, required this.process, Key? key})
: super(key: key);
@override
State<LabelButton> createState() => _LabelButtonState();
const LabelButton._(this.label, this.process, {Key? key})
: super(key: key);
static LabelButton createBlank() {
return const LabelButton._(null, null);
}
}
class _LabelButtonState extends State<LabelButton> {
bool _hasBeenPressed = false;
@override
Widget build(BuildContext context) {
if (widget.label != null) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Material(
child: InkWell(
highlightColor: Color(0xFF00D3F8).withOpacity(0.3),
splashColor: Color(0xFFB20DD3).withOpacity(0.3),
onTap: () {
setState(() async {
/*Timer(Duration(seconds: 3), (){
_hasBeenPressed = !_hasBeenPressed;
print("inside" + _hasBeenPressed.toString()); //prints true
});
_hasBeenPressed = !_hasBeenPressed;
print(_hasBeenPressed); // prints false
*/
_hasBeenPressed = true;
print("CLICKED");
await Future.delayed(const Duration(seconds: 3), () {
print("nach");
_hasBeenPressed = false;
});
print(_hasBeenPressed);
});
widget.process!(widget.label!.identifier, widget.label!.category, widget.label!.id);
HapticFeedback.lightImpact();
},
child: Ink(
width: 100, // Breite anpassen
height: 120, // Höhe anpassen
//padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: _hasBeenPressed ? const Color(0xFFB6B6B6) : Colors.green
/*border: Border.all(
color: Colors.black, // Rahmenfarbe anpassen
width: 2, // Rahmendicke anpassen
),*/
//borderRadius: BorderRadius.circular(12), // Eckradius anpassen
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(iconList
.firstWhere((element) => element.name == widget.label!.uiIcon)
.icon,
size: 80,),
/*const Icon(CustomIcons.construction,
size: 80,),*/
Text(widget.label!.categoryName,
style: const TextStyle(
color: Color(0xFF696969),
//fontWeight: FontWeight.bold,
)),
Text(widget.label!.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
)), // Text unter dem Icon
],
),
),
),
)
)
);
}
else {
return Container();
}
}
}
答案1
得分: 1
I don't understand what you are trying to do.
但你需要更正一些东西,即 setState(() async {
,setState 不能被异步执行。你可以按照以下方式进行:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool hasClicked = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: InkWell(
onTap: () async {
if (hasClicked) {
setState(() {
hasClicked = !hasClicked;
});
} else {
await Future.delayed(const Duration(seconds: 3), () {
setState(() {
hasClicked = !hasClicked;
});
});
}
},
child: Container(
decoration: BoxDecoration(
color: hasClicked ? Colors.red : Colors.green,
),
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headline6,
),
),
),
),
),
);
}
}
如果你想要...
英文:
i don't what you are trying to do.
but you need to correct few thing i.e, setState(() async {
setState can not be done async. you can do as below.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool hasclicked = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: InkWell(
onTap: () async {
if (hasclicked) {
setState(() {
hasclicked = !hasclicked;
});
} else {
await Future.delayed(const Duration(seconds: 3), () {
setState(() {
hasclicked = !hasclicked;
});
});
}
},
child: Container(
decoration: BoxDecoration(
color: hasclicked ? Colors.red : Colors.green,
),
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headlineMedium,
))),
),
),
);
}
}
if you want
答案2
得分: 1
你在执行setState((){});
之前等待了几秒钟。这是导致问题的原因。
....
onTap: () async {
........
_hasBeenPressed = true;
setState(() {});
await Future.delayed(const Duration(seconds: 3), () {
print("nach");
_hasBeenPressed = false;
setState(() {});
});
............
}
英文:
You are awaiting for few seconds before firing setState((){});
. That's causing the issue.
....
onTap: () async {
........
_hasBeenPressed = true;
setState(() {});
await Future.delayed(const Duration(seconds: 3), () {
print("nach");
_hasBeenPressed = false;
setState(() {});
});
............
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论