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'),
),
)
]);
},
),
Больше примеров можно найти здесь .