Home > Mobile >  Flutter: Programatically perform a button click
Flutter: Programatically perform a button click

Time:11-10

How can you programatically perform a button click in Flutter? I basically want to bind a number of buttons to keys on the keyboard, the most important part is that after a key is pressed the corresponding button the visual state of the button is triggered to inform the user which button was pressed.

I am aware you can invoke the onTap function, but that by itself doesn't update the visual state of button. Is there a way to simulate this kind of behavior, I tried to look into MaterialStateController but doesn't feel like it's the right approach.

CodePudding user response:

I was going to say that you could use the MaterialStateController to simulate that the button has been pressed.

This can be done by updating the state controller in some good enough fashion of your choice. Something like this perhaps:

enter image description here

Non-optimized code for this (you will bind to keys on the keyboard instead):

ElevatedButton(
  onPressed: () async {
    button2StatesController.update(MaterialState.pressed, true);
    await Future.delayed(const Duration(milliseconds: 200));
    button2StatesController.update(MaterialState.pressed, false);
  },
  child: const Text('Button 1'),
),
ElevatedButton(
  onPressed: () {},
  statesController: button2StatesController,
  child: const Text('Button 2'),
)

You cannot simulate the InkWell effect (as far as I know) without more intervention. Like creating your own button with your own inkwell animations etc...

CodePudding user response:

I discovered that _InkWellResponseState (internal-) classes have a function called simulateTap. The function is bound against ActivateIntent and by default this intend is fired whenever the user presses Enter or Space


class SimActivateIntent extends ActivateIntent {
  const SimActivateIntent (this.model);
  final FocusNode model;
}

class SimActivateAction extends Action<SimActivateIntent> {
  SimActivateAction ();
  @override
  void invoke(covariant SimActivateIntentintent) {
    Actions.maybeInvoke(intent.model.context!, const ActivateIntent());
  }
}

With the intends listed above one can invoke the ActivateIntent on a specific object and simulate a button press. They can bound into the application using Shortcuts & Actions classes.

Map<ShortcutActivator, Intent> get defaultShortcuts {
    return <ShortcutActivator, Intent>{
       const SingleActivator(LogicalKeyboardKey.backspace):
          SimActivateIntent(digitBackspace),
    }
}

@override
Widget build(BuildContext context)
{
    return Shortcuts(
      shortcuts: defaultShortcuts,
      child: Actions(
      actions: <Type, Action<Intent>>{
        SimActivateIntent: SimActivateAction(),
      },
      child: ...
    ));
}
  • Related