How to debounce Textfield onChange in Dart?

后端 未结 9 1168
攒了一身酷
攒了一身酷 2020-12-03 04:49

I\'m trying to develop a TextField that update the data on a Firestore database when they change. It seems to work but I need to prevent the onChange event to fire multiple

相关标签:
9条回答
  • 2020-12-03 04:56

    Using BehaviorSubject from rxdart lib is a good solution. It ignores changes that happen within X seconds of the previous.

    final searchOnChange = new BehaviorSubject<String>();
    ...
    TextField(onChanged: _search)
    ...
    
    void _search(String queryString) {
      searchOnChange.add(queryString);
    }   
    
    void initState() {    
      searchOnChange.debounceTime(Duration(seconds: 1)).listen((queryString) { 
      >> request data from your API
      });
    }
    
    0 讨论(0)
  • 2020-12-03 04:59

    You can use rxdart package to create an Observable using a stream then debounce it as per your requirements. I think this link would help you get started.

    0 讨论(0)
  • 2020-12-03 05:03

    You can make Debouncer class using Timer

    import 'package:flutter/foundation.dart';
    import 'dart:async';
    
    class Debouncer {
      final int milliseconds;
      VoidCallback action;
      Timer _timer;
    
      Debouncer({ this.milliseconds });
    
      run(VoidCallback action) {
        if (_timer != null) {
          _timer.cancel();
        }
    
        _timer = Timer(Duration(milliseconds: milliseconds), action);
      }
    }
    

    Declare it

    final _debouncer = Debouncer(milliseconds: 500);
    

    and trigger it

    onTextChange(String text) {
      _debouncer.run(() => print(text));
    }
    
    0 讨论(0)
  • 2020-12-03 05:08

    Here is my solution

     subject = new PublishSubject<String>();
          subject.stream
              .debounceTime(Duration(milliseconds: 300))
              .where((value) => value.isNotEmpty && value.toString().length > 1)
              .distinct()
              .listen(_search);
    
    0 讨论(0)
  • 2020-12-03 05:09

    As others have suggested, implementing a custom debouncer class is not that difficult. You can also use a Flutter plugin, such as EasyDebounce.

    In your case you'd use it like this:

    import 'package:easy_debounce/easy_debounce.dart';
    
    ...
    
    // Start listening to changes 
    nomeTextController.addListener(((){
        EasyDebounce.debounce(
            '_updatenomecliente',        // <-- An ID for this debounce operation
            Duration(milliseconds: 500), // <-- Adjust Duration to fit your needs
            () => _updateNomeCliente()
        ); 
    }));
    

    Full disclosure: I'm the author of EasyDebounce.

    0 讨论(0)
  • 2020-12-03 05:09

    Here's my two cents with preemptive debouncing.

    import 'dart:async';
    
    /// Used to debounce function call.
    /// That means [runnable] function will be called at most once per [delay].
    class Debouncer {
      int _lastTime;
      Timer _timer;
      Duration delay;
    
      Debouncer(this.delay)
          : _lastTime = DateTime.now().millisecondsSinceEpoch;
      
      run(Function runnable) {
        _timer?.cancel();
    
        final current = DateTime.now().millisecondsSinceEpoch;
        final delta = current - _lastTime;
    
        // If elapsed time is bigger than [delayInMs] threshold -
        // call function immediately.
        if (delta > delay.inMilliseconds) {
          _lastTime = current;
          runnable();
        } else {
          // Elapsed time is less then [delayInMs] threshold -
          // setup the timer
          _timer = Timer(delay, runnable);
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题