不推荐使用文本选择控件,改为用户 contextMenuBuilder

Ram*_*say 5 flutter

我已经实现了一个自定义文本选择控件,以在突出显示的文本上的默认复制/粘贴/selectAll 旁边添加一个打开地图按钮,如下所示:

class MapTextSelectionControls extends MaterialTextSelectionControls {
  // Padding between the toolbar and the anchor.
  static const double _toolbarContentDistanceBelow = 20.0;
  static const double _toolbarContentDistance = 8.0;

  MapTextSelectionControls();

  @override
  Widget buildToolbar(
      BuildContext context,
      Rect globalEditableRegion,
      double textLineHeight,
      Offset selectionMidpoint,
      List<TextSelectionPoint> endpoints,
      TextSelectionDelegate delegate,
      ClipboardStatusNotifier? clipboardStatus,
      Offset? lastSecondaryTapDownPosition,
      ) {
    //.. some code here

    return MapSelectionToolbar(
      anchorAbove: anchorAbove,
      anchorBelow: anchorBelow,
      clipboardStatus: clipboardStatus,
      handleCopy: canCopy(delegate)
          ? () => handleCopy(delegate, clipboardStatus)
          : null,
      handleMap: selectedText.isNotEmpty
          ? () {
        openLink(generateLocationLinkFromQuery(selectedText));
        delegate.hideToolbar();
      }
          : null,
      handleCut: canCut(delegate) ? () => handleCut(delegate) : null,
      handlePaste: canPaste(delegate) ? () => handlePaste(delegate) : null,
      handleSelectAll:
      canSelectAll(delegate) ? () => handleSelectAll(delegate) : null,
    );
  }
}

class MapSelectionToolbar extends StatefulWidget { ....

SelectableRegion(
        selectionControls: MapTextSelectionControls(),
        focusNode: _selectableRegionFocusNode, ....)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

然而,Flutter 警告说,我现在实现它的方式即将被弃用,但我无法弄清楚或找到足够的资源来了解如何实现相同结果的新方法。

在此输入图像描述

Hub*_*bel 2

Flutter 3.7 有一种新的方式来实现上下文菜单。以下是详细信息和示例:自定义上下文菜单的新方法 您可以执行以下操作:

SelectableText(
  "Lorem ipsum dolor sit amet",
  contextMenuBuilder: (context, editableTextState) {
    final TextEditingValue value = editableTextState.textEditingValue;
    final List<ContextMenuButtonItem> buttonItems = editableTextState.contextMenuButtonItems;
    buttonItems.insert(
      0,
      ContextMenuButtonItem(
        label: 'Send email',
        onPressed: () {
          // your "send email" code    
        },
      ),
    );
    return AdaptiveTextSelectionToolbar.buttonItems(
      anchors: editableTextState.contextMenuAnchors,
      buttonItems: buttonItems,
    );
  },
)
Run Code Online (Sandbox Code Playgroud)

另一个带有 SelectionArea 和可编辑文本范围的示例:

SelectionArea(
        onSelectionChanged: (value) {
          selectedText = value?.plainText ?? "";
        },
        contextMenuBuilder: (context, editableTextState) {
          final List<ContextMenuButtonItem> buttonItems = editableTextState.contextMenuButtonItems;
          buttonItems.insert(
            0,
            ContextMenuButtonItem(
              label: 'Send email',
              onPressed: () {
                debugPrint("send \"$selectedText\" by email");
                // your "send email" code
              },
            ),
          );
          return AdaptiveTextSelectionToolbar.buttonItems(
            anchors: editableTextState.contextMenuAnchors,
            buttonItems: buttonItems,
          );
        },
        child: Scaffold(
          appBar: AppBar(title: const Text(_title)),
          body: const Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Lorem ipsum dolor sit amet, ',
                ),
                SizedBox(height: 10),
                Text.rich(
                  TextSpan(
                    text: "consetetur sadipscing elitr",
                  ),
                ),
              ],
            ),
          ),
        ),
      )
Run Code Online (Sandbox Code Playgroud)