dart 阻止Flutter的TextField的撤销键盘命令以进行自定义实现

yhqotfr8  于 2023-09-28  发布在  Flutter
关注(0)|答案(2)|浏览(124)

我正在用Flutter开发一个应用程序,其中包括用于文本输入的TextField小部件。我的目标是通过自定义实现手动处理撤销和重做,绕过Flutter的内置功能。
这是我的问题:即使我尝试用RawKeyboardListener这样的小部件 Package TextField来捕获键盘事件,TextField似乎仍然在内部管理撤销和重做。有没有其他方法来阻止这些并进行自定义实现?

fsi0uk1n

fsi0uk1n1#

更新:我在代码中添加了更多的可能性。我创建了两个函数来防止此类操作。第一个用于撤消操作,第二个用于重做操作。
我们所做的是,每当用户执行撤销或重做操作时,我们都会阻止该操作的发生。
我们在那里创建了我们的功能。因此,每当用户在那时执行撤销操作时,preventPerformingUndo()函数将调用&每当用户在那时执行重做操作时,preventPerformingRedo()函数将调用。
原始程式码:

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: MyWidget());
  }
}

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

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final TextEditingController textEditingController = TextEditingController();

  @override
  void dispose() {
    textEditingController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RawKeyboardListener(
              focusNode: FocusNode(),
              onKey: (RawKeyEvent value) {
                // For Control & Command Key
                final bool isControlPressed = value.isControlPressed;
                final bool isMetaPressed = value.isMetaPressed;
                final bool isControlOrMeta = isControlPressed || isMetaPressed;

                // For Z Key
                final bool isLZ = value.logicalKey == LogicalKeyboardKey.keyZ;
                final bool isPZ = value.physicalKey == PhysicalKeyboardKey.keyZ;
                final bool isLogicalOrPhysicalZ = isLZ || isPZ;

                // For Y Key
                final bool isLY = value.logicalKey == LogicalKeyboardKey.keyY;
                final bool isPY = value.physicalKey == PhysicalKeyboardKey.keyY;
                final bool isLogicalOrPhysicalY = isLY || isPY;

                if (isControlOrMeta && isLogicalOrPhysicalZ) {
                  preventPerformingUndo();
                } else {}

                if (isControlOrMeta && isLogicalOrPhysicalY) {
                  preventPerformingRedo();
                } else {}
              },
              child: TextField(
                controller: textEditingController,
              ),
            ),
            const SizedBox(height: 16),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                ElevatedButton(
                  onPressed: preventPerformingUndo,
                  child: const Text("Perform Undo"),
                ),
                ElevatedButton(
                  onPressed: preventPerformingRedo,
                  child: const Text("Perform Redo"),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  void preventPerformingUndo() {
    // What to do if user pressed Ctrl + Z
    return;
  }

  void preventPerformingRedo() {
    // What to do if user pressed Ctrl + Y
    return;
  }
}
shyt4zoc

shyt4zoc2#

您可以将UndoHistoryController传递给TextField。UndoHistoryController是一个ValueNotifier,用于通知附加的监听器UndoHistoryValue的变化。
创建UndoHistoryController的示例。

final UndoHistoryController undoController = UndoHistoryController();

将其传递给TextField,使用ValueListenableBuilder监听该示例,并在构建器中的按钮上返回一行,以执行撤消/重做操作。
下面是一些示例,以便更好地理解

Widget build(BuildContext context) {

 return  Scaffold(
  body: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      TextField(
        controller: controller,
        focusNode: focusNode,
        undoController: undoController,
      ),
      ValueListenableBuilder<UndoHistoryValue>(
        valueListenable: undoController,
        builder: (BuildContext context, UndoHistoryValue value,
            Widget? child) {
          return Row(
            children: <Widget>[
              TextButton(
                child: Text('Undo'),
                onPressed: () {
                  undoController.undo();
                },
              ),
              TextButton(
                child: Text('Redo'),
                onPressed: () {
                  undoController.redo();
                },
              ),
            ],
          );
        },
      ),
    ],
  ),
 );
}

单击“撤消”和“重做”按钮将分别从TextField值中删除和重新应用更改

相关问题