Keyboard Shortcuts - wurzelsand/flutter-memos GitHub Wiki

Keyboard Shortcuts

Shortcuts if focused

Ein Container soll im Focus stehen und dabei seine Farbe in Rot, Grün oder Blau ändern, wenn ich die Taste R, G oder B drücke.

Ausführung

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
        home: Scaffold(
          body: ExampleWidget(),
        )
    );
  }
}

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({super.key});

  @override
  State createState() => _ExampleWidgetState();
}

class FillRedIntent extends Intent { const FillRedIntent(); }
class FillGreenIntent extends Intent { const FillGreenIntent(); }
class FillBlueIntent extends Intent { const FillBlueIntent(); }

class _ExampleWidgetState extends State<ExampleWidget> {
  Color _color = Colors.transparent;

  void _fillWith(Color color) {
    setState(() => _color = color);
  }

  @override
  Widget build(BuildContext context) {
    return Shortcuts(
      shortcuts: const <ShortcutActivator, Intent>{
        SingleActivator(LogicalKeyboardKey.keyR): FillRedIntent(),
        SingleActivator(LogicalKeyboardKey.keyG): FillGreenIntent(),
        SingleActivator(LogicalKeyboardKey.keyB): FillBlueIntent(),
      },
      child: Actions(
        actions: <Type, Action<Intent>>{
          FillRedIntent: CallbackAction(onInvoke: (_) => _fillWith(Colors.red)),
          FillGreenIntent: CallbackAction(onInvoke: (_) => _fillWith(Colors.green)),
          FillBlueIntent: CallbackAction(onInvoke: (_) => _fillWith(Colors.blue)),
        },
        child: Focus(
          autofocus: true,
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(),
              color: _color,
            ),
            width: 300,
            height: 100,
          )
        )
      )
    );
  }
}

Global Shortcuts

Ich möchte das gleiche Programm schreiben. Diesmal soll der Shortcut unabhängig vom Focus sein. Die Shortcuts sind diesmal Shift-R, Shift-G und Shift-B.

Ausführung

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
        home: Scaffold(
          body: ExampleWidget(),
        )
    );
  }
}

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({super.key});

  @override
  State createState() => _ExampleWidgetState();
}

class _ExampleWidgetState extends State<ExampleWidget> {
  Color _color = Colors.transparent;

  void _fillWith(Color color) {
    setState(() => _color = color);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(),
        color: _color,
      ),
      width: 300,
      height: 100,
    );
  }

  @override
  void initState() {
    super.initState();
    RawKeyboard.instance.addListener(_handleKey);
  }

  @override
  void dispose() {
    RawKeyboard.instance.removeListener(_handleKey);
    super.dispose();
  }

  static bool isKeyDown(Set<LogicalKeyboardKey> keys) { // #1
    return keys.intersection(RawKeyboard.instance.keysPressed).isNotEmpty;
  }

  void _handleKey(event) {
    if (event is RawKeyDownEvent) {
      bool isShiftDown = isKeyDown({
        LogicalKeyboardKey.shiftLeft,
        LogicalKeyboardKey.shiftRight,
      });
      if (isShiftDown) {
        if (event.logicalKey == LogicalKeyboardKey.keyR) {
          _fillWith(Colors.red);
        } else if (event.logicalKey == LogicalKeyboardKey.keyG) {
          _fillWith(Colors.green);
        } else if (event.logicalKey == LogicalKeyboardKey.keyB) {
          _fillWith(Colors.blue);
        }
      }
    }
  }
}

Anmerkungen

  1. Man könnte auf die Funktion verzichten und so vereinfachen:

    void _handleKey(RawKeyEvent event) {
        if (event.isShiftPressed) {
          if (event.logicalKey == LogicalKeyboardKey.keyR) {
            _fillWith(Colors.red);
          } else if (event.logicalKey == LogicalKeyboardKey.keyG) {
            _fillWith(Colors.green);
          } else if (event.logicalKey == LogicalKeyboardKey.keyB) {
            _fillWith(Colors.blue);
          }
        }
    }
⚠️ **GitHub.com Fallback** ⚠️