【问题标题】:Flutter: how to build a custom toolbar for Selectable Text~Flutter:如何为 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 框架本身的问题吗?

【问题讨论】:

    标签: flutter textselection flutter-text flutter-exception


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多