Flutter:如何为 Selectable Text 构建自定义工具栏~

Posted

技术标签:

【中文标题】Flutter:如何为 Selectable Text 构建自定义工具栏~【英文标题】:Flutter: how to build a custom toolbar for Selectable Text~ 【发布时间】:2021-07-27 07:45:36 【问题描述】:

我正在构建一个 ChatApp,我需要一个允许用户从小部件中选择文本并显示我的一些自定义操作的功能,例如删除该消息、分享等。

我发现 SelectableText 小部件会很有帮助,但唯一的缺点是我必须创建一个自定义 TextSelectionControls 类并将其传递给 SelectableText 小部件 selectionControls 属性才能添加我自己的操作,但我真的不知道该怎么做,那么有人知道如何创建这种类吗?

我已经访问过这个链接:Github: Custom text selection menu example,但是在我复制并粘贴他的代码后,它在编译时向我显示了这个错误消息:

Missing concrete implementations of 'TextSelectionControls.buildHandle', 'TextSelectionControls.getHandleAnchor', and 'TextSelectionControls.getHandleSize'.

尝试实现缺少的方法,或将类设为 abstract.dart(non_abstract_class_inherits_abstract_member)

但我不认为我错过了什么,因为 Github 上的人没有,所以是因为 Flutter 框架本身的问题吗?

【问题讨论】:

【参考方案1】:

您提供的链接中的代码有效。你确定你在使用

class MyMaterialTextSelectionControls extends MaterialTextSelectionControls

这是重构的工作示例

class MyMaterialTextSelectionControls extends MaterialTextSelectionControls 
  // Padding between the toolbar and the anchor.
  static const double _kToolbarContentDistanceBelow = 10.0;
  static const double _kToolbarContentDistance = 8.0;

  /// Builder for material-style copy/paste text selection toolbar.
  @override
  Widget buildToolbar(
    BuildContext context,
    Rect globalEditableRegion,
    double textLineHeight,
    Offset selectionMidpoint,
    List<TextSelectionPoint> endpoints,
    TextSelectionDelegate delegate,
    ClipboardStatusNotifier clipboardStatus,
    Offset? lastSecondaryTapDownPosition,
  ) 
    final TextSelectionPoint startTextSelectionPoint = endpoints[0];
    final TextSelectionPoint endTextSelectionPoint =
        endpoints.length > 1 ? endpoints[1] : endpoints[0];
    final Offset anchorAbove = Offset(
      globalEditableRegion.left + selectionMidpoint.dx,
      globalEditableRegion.top +
          startTextSelectionPoint.point.dy -
          textLineHeight -
          _kToolbarContentDistance,
    );
    final Offset anchorBelow = Offset(
      globalEditableRegion.left + selectionMidpoint.dx,
      globalEditableRegion.top +
          endTextSelectionPoint.point.dy +
          _kToolbarContentDistanceBelow,
    );
    final value = delegate.textEditingValue;
    return MyTextSelectionToolbar(
      anchorAbove: anchorAbove,
      anchorBelow: anchorBelow,
      clipboardStatus: clipboardStatus,
      handleCustomButton: () 
        print(value.selection.textInside(value.text));
        delegate.hideToolbar();
      ,
    );
  


class MyTextSelectionToolbar extends StatelessWidget 
  const MyTextSelectionToolbar(
    Key? key,
    required this.anchorAbove,
    required this.anchorBelow,
    required this.clipboardStatus,
    required this.handleCustomButton,
  ) : super(key: key);

  final Offset anchorAbove;
  final Offset anchorBelow;
  final ClipboardStatusNotifier clipboardStatus;
  final VoidCallback? handleCustomButton;

  @override
  Widget build(BuildContext context) 
    assert(debugCheckHasMaterialLocalizations(context));

    final List<_TextSelectionToolbarItemData> items =
        <_TextSelectionToolbarItemData>[
      _TextSelectionToolbarItemData(
        onPressed: handleCustomButton ?? () ,
        label: 'Custom button',
      ),
    ];

    int childIndex = 0;
    return TextSelectionToolbar(
      anchorAbove: anchorAbove,
      anchorBelow: anchorBelow,
      toolbarBuilder: (BuildContext context, Widget child) =>
          Container(color: Colors.pink, child: child),
      children: items
          .map((_TextSelectionToolbarItemData itemData) =>
              TextSelectionToolbarTextButton(
                padding: TextSelectionToolbarTextButton.getPadding(
                    childIndex++, items.length),
                onPressed: itemData.onPressed,
                child: Text(itemData.label),
              ))
          .toList(),
    );
  


class _TextSelectionToolbarItemData 
  const _TextSelectionToolbarItemData(
    required this.label,
    required this.onPressed,
  );

  final String label;
  final VoidCallback onPressed;

无论如何你可以检查这个包text_selection_controls

【讨论】:

以上是关于Flutter:如何为 Selectable Text 构建自定义工具栏~的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 如何为 IconButton 赋予颜色?

Flutter:如何为“选定”的 ListTile 设置文本颜色?

Flutter:如何为 StreamBuilder 制作 http 流

如何为 Flutter 中的文本赋予边框/背景?

Flutter - 如何为消息应用程序实现通知?

如何为 Flutter 添加额外的 iOS 模拟器?