2

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

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

我已经访问了这个链接:Github:自定义文本选择菜单示例,但是在我复制并粘贴他的代码之后,它在编译时向我显示了这个错误消息:

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

尝试实现缺少的方法,或创建类 abstract.dart(non_abstract_class_inherits_abstract_member)

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

4

1 回答 1

0

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

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

于 2021-12-24T08:39:46.947 回答