Home > Software engineering >  How to put a timer on a ExpansionTile to avoid 2 clicks in less than 1.5 seconds?
How to put a timer on a ExpansionTile to avoid 2 clicks in less than 1.5 seconds?

Time:03-03

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();
}
  • Related