我需要知道用户单击按钮时是否按下(按下)某个键

D. *_*Joe 4 dart flutter flutter-desktop

在 Flutter 桌面应用程序中,我想知道当用户用鼠标单击按钮时,他们是否也按住了某个键(如 Shift、Control、Alt 等)。

如何才能做到这一点?

编辑

我最初的问题不够清楚。

我有一个动态复选框列表,我想使用 SHIFT+单击来选择最后一个选定的复选框和按下 SHIFT 选定的复选框之间的所有内容。

我看过 FocusNode 但这似乎只适用于 1 个元素。

Chr*_*ore 7

这可以通过FocusNode.

您将需要一个有状态的小部件,您可以在其中使用初始化节点。您需要attach节点并定义按下键盘时调用的回调。然后,您可以向节点请求焦点,requestFocus以便该节点接收键盘事件。

您还需要调用_nodeAttachment.reparent();您的build方法。您还应该将该节点放置在dispose.

下面的示例打印 true 或 false 来判断按下按钮时是否按下了 Shift 键。这可以通过 和 isControlPressed属性轻松扩展到其他键,例如 control 和 alt isAltPressed


完整示例:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  late final FocusNode focus;
  late final FocusAttachment _nodeAttachment;
  
  bool isShiftPressed = false;
  
  @override
  void initState() {
    super.initState();
    focus = FocusNode(debugLabel: 'Button');
    _nodeAttachment = focus.attach(context, onKey: (node, event) {
      isShiftPressed = event.isShiftPressed;
    });
    focus.requestFocus();
  }
  
  @override
  void dispose() {
    focus.dispose();
    super.dispose();
  }
  
  Widget build(BuildContext context) {
    _nodeAttachment.reparent();
    return TextButton(
      onPressed: () {
        print(isShiftPressed);
      },
      child: Text('Test'),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

您仍然可以使用此解决方案来解决更具体的问题。将上面的示例包含在您的复选框列表中。您可以做一些简单的逻辑来获得您想要的行为。如果我这里的内容不准确,您应该能够轻松地根据您的需要进行修改。然而,这证明您可以根据需要使用此方法,即使逻辑中的某些细节不准确:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  late final FocusNode focus;
  late final FocusAttachment _nodeAttachment;
  
  bool isShiftPressed = false;
  
  List<bool> checkboxStates = List.filled(5, false);
  
  int lastClicked = -1;
  
  @override
  void initState() {
    super.initState();
    focus = FocusNode(debugLabel: 'Button');
    _nodeAttachment = focus.attach(context, onKey: (node, event) {
      isShiftPressed = event.isShiftPressed;
    });
    focus.requestFocus();
  }
  
  @override
  void dispose() {
    focus.dispose();
    super.dispose();
  }
  
  Widget build(BuildContext context) {
    _nodeAttachment.reparent();
    return Column(
      children: List.generate(checkboxStates.length, (index) => Checkbox(
        value: checkboxStates[index],
        onChanged: (val) {
          if(val == null) {
            return;
          }
          
          setState(() {            
            if(isShiftPressed && val) {
              if(lastClicked >= 0) {
                bool loopForward = lastClicked < index;
                if(loopForward) {
                  for(int x = lastClicked; x < index; x++) {
                    checkboxStates[x] = true;
                  }
                }
                else {
                  for(int x = lastClicked; x > index; x--) {
                    checkboxStates[x] = true;
                  }
                }
              }
            }
            checkboxStates[index] = val;
          });
          
          if(val) {
            lastClicked = index;
          }
          else {
            lastClicked = -1;
          }
          
          print('Checkbox $index: $isShiftPressed');
        }
      )),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)