I Have RawKeyboardListener that invoke _getIDCardInfo each time KeyDown is press and hold.

the problem is _getIDCardInfo is invoked multiple times. this make problem because scrollcontroller.animateTo is animated only in the last time _getIDCardInfo is invoked.

I want scrollcontroller.animateTo is animated each time _getIDCardInfo is invoked, not only in the last call of _getIDCardInfo.

how can i make _getIdCardInfo() is invoked syncronously. or there is any way scrollController can be animated properly without getting invoked multiple times.

  _getIdCardInfo() async {
    try {
      final String result = await platform.invokeMethod('scanIDCard');
      await _myItems.insert(0, {"id": result});
      await _scrollController.animateTo(
          _scrollController.position.maxScrollExtent,
          curve: Curves.easeIn,
          duration: Duration(milliseconds: 30));
      await _scrollController.animateTo(0,
          curve: Curves.easeIn, duration: Duration(milliseconds: 50));
    } on PlatformException catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    FocusNode _focusNode = FocusNode();
    return RawKeyboardListener(
      focusNode: _focusNode,
      autofocus: true,
      onKey: (RawKeyEvent event) async {
        if ((event.runtimeType == RawKeyDownEvent &&
            event.logicalKey.keyId == 1108101562648)) {
          await _getIdCardInfo();
        }
      },
    );
  }
}


Solution 1: Igor Kharakhordin

I guess what you need is to run animation recursively like this:

  final _scrollController = ScrollController();
  final _focusNode = FocusNode();

  int _animateTimes = 0;        // How many times we need to run an animation
  Future<void> _animateFuture;  // Is animation currently running

  Future<void> _getIdCardInfo() async {    
    await _scrollController.animateTo(
      Random().nextInt(1000).toDouble(),
      duration: Duration(milliseconds: 1000), 
      curve: Curves.linear
    );

    _runNext();
  }

  void _runAnimation() {
    _animateTimes++;

    if (_animateFuture == null) {
      _animateFuture = _getIdCardInfo();
    }
  }

  void _runNext() {
    _animateTimes--;
    _animateFuture = null;

    if (_animateTimes > 0) {
      _animateFuture = _getIdCardInfo();
    }
  }

  @override
  void dispose() {
    _focusNode.dispose(); // Don't forget to dispose of focus node
    super.dispose();
  }
...
RawKeyboardListener(
  focusNode: _focusNode,
  autofocus: true,
  onKey: (RawKeyEvent event) async {
    if (event is RawKeyDownEvent && event.logicalKey.keyId == 1108101562648) {
      _runAnimation();
    }
  },
  child: Text('asd')
),
...