我需要知道用户单击按钮时是否按下(按下)键
I need to know if a key was down (pressed) while the user clicked on a button
在 Flutter 桌面应用程序中,我想知道当用户用鼠标单击按钮时,他们是否同时按住了一个键(如 Shift、Control、Alt 等)。
如何做到这一点?
编辑
我最初的问题不够清楚。
我有一个复选框的动态列表,我想使用 SHIFT+单击 select 最后一个 selected 的复选框和用 SHIFT selected 的那个之间的所有内容下来。
我查看了 FocusNode,但它似乎只适用于 1 个元素。
这可以通过 FocusNode
来完成。
您需要一个有状态的小部件,您可以在其中使用初始化节点。您需要 attach
节点并定义在键盘按下时调用的回调。然后你可以使用 requestFocus
从节点请求焦点,以便节点接收键盘事件。
您还需要在 build
方法中调用 _nodeAttachment.reparent();
。您还应该在 dispose
.
中处理节点
下面的示例打印 true 或 false 来确定按下按钮时是否按下了 shift 键。这可以很容易地扩展到其他键,如 control 和 alt,具有 isControlPressed
和 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'),
);
}
}
您仍然可以使用此解决方案来解决更具体的问题。将上面的示例包裹在您的复选框列表中。您可以执行一些简单的逻辑来获得预期的行为。如果我这里的内容不准确,您应该能够轻松地根据您的需要进行修改。这证明您可以根据需要使用此方法,但是,即使逻辑中的某些细节不准确:
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');
}
)),
);
}
}
在 Flutter 桌面应用程序中,我想知道当用户用鼠标单击按钮时,他们是否同时按住了一个键(如 Shift、Control、Alt 等)。
如何做到这一点?
编辑
我最初的问题不够清楚。
我有一个复选框的动态列表,我想使用 SHIFT+单击 select 最后一个 selected 的复选框和用 SHIFT selected 的那个之间的所有内容下来。
我查看了 FocusNode,但它似乎只适用于 1 个元素。
这可以通过 FocusNode
来完成。
您需要一个有状态的小部件,您可以在其中使用初始化节点。您需要 attach
节点并定义在键盘按下时调用的回调。然后你可以使用 requestFocus
从节点请求焦点,以便节点接收键盘事件。
您还需要在 build
方法中调用 _nodeAttachment.reparent();
。您还应该在 dispose
.
下面的示例打印 true 或 false 来确定按下按钮时是否按下了 shift 键。这可以很容易地扩展到其他键,如 control 和 alt,具有 isControlPressed
和 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'),
);
}
}
您仍然可以使用此解决方案来解决更具体的问题。将上面的示例包裹在您的复选框列表中。您可以执行一些简单的逻辑来获得预期的行为。如果我这里的内容不准确,您应该能够轻松地根据您的需要进行修改。这证明您可以根据需要使用此方法,但是,即使逻辑中的某些细节不准确:
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');
}
)),
);
}
}