Flutter: как создать настраиваемую панель инструментов для выделяемого текста ~

Я создаю приложение 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?

Плюс: я не могу исключить больше пакетов, потому что размер моего приложения уже составляет 200 МБ !!! :(

2 ответа

Код по предоставленной вами ссылке работает. Вы уверены, что используете

      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 3.7 вы можете легко добавлять настраиваемые контекстные действия к любому виджету, включая текстовые виджеты.

      SelectableText(
              'My Text',
              contextMenuBuilder: (context, editableTextState) {
              return AdaptiveTextSelectionToolbar(
                  anchors: editableTextState.contextMenuAnchors,
                  children: [
                    InkWell(
                      onTap: (){},
                      child: SizedBox(
                        width: 200.0,
                        child: Text('Note'),
                      ),
                    )
                  ]);
            },
          ),

Больше примеров можно найти здесь .

Другие вопросы по тегам