I have the code below in which every item from the list is an ExpansionTile and when I click in one of them it loads data from stream and shows Prod() content. My question is how can I put a timer to only accept clicks (openings) of the expansiontiles after 1.5 seconds? This is the code.
ListView.
builder(
key: Key('builder ${selected}'),
itemCount: items.length,
itemBuilder: (context, index) {
return ExpansionTile(
title: Text('${items[index].cod}', style: TextStyle(fontWeight: FontWeight.bold),),
children: [
Container(
height: MediaQuery.of(context).size.height * 0.75,
width: MediaQuery.of(context).size.width,
child: Prod(items[index]),
),
],
onPressed: (){
// Code which loads data from stream
},
),
onExpansionChanged: ((newState) {
if(newState){
setState(() {
selected = index;
});
}else{
setState(() {
selected = -1;
});
}
}),
key: Key(index.toString()),
initiallyExpanded: index == selected,
);
},
)
CodePudding user response:
As part of your state object you can have a DateTime object. When the click handling routine is called check how many seconds have passed and reset the timer if you execute the code again:
DateTime clickTimer = DateTime.now();
...
onPressed: () {
if(DateTime.now().difference(clickTimer).inMilliseconds > 1500) {
clickTimer = DateTime.now();
//Do your thing
} else {
//Tell user they are clicking too much
}
}
CodePudding user response:
You can make a debouncer using Timer
class
Timer? debouncer;
// Add listener
onPressExpansionTile() {
if (debouncer?.isActive ?? false) debouncer.cancel();
debouncer = Timer(const Duration(milliseconds: 1500), () {
// Code which loads data from stream
});
}
Usage
ExpansionTile(
onPressed:onPressExpansionTile,
//..
),
Dispose of the timer
@override
void dispose() {
_debouncer?.cancel();
super.dispose();
}