getAdaptiveButtons static method
Iterable<Widget>
getAdaptiveButtons(
- BuildContext context,
- List<
ContextMenuButtonItem> buttonItems
Returns a List of Widgets generated by turning buttonItems into the
default context menu buttons for the current platform.
This is useful when building a text selection toolbar with the default button appearance for the given platform, but where the toolbar and/or the button actions and labels may be custom.
This sample demonstrates how to use getAdaptiveButtons to generate
default button widgets in a custom toolbar.
To see it in action, copy and run this code snippet on DartPad.
// This example demonstrates how to create a custom toolbar that retains the
// look of the default buttons for the current platform.
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:material_ui/material_ui.dart';
void main() => runApp(const EditableTextToolbarBuilderExampleApp());
class EditableTextToolbarBuilderExampleApp extends StatefulWidget {
const EditableTextToolbarBuilderExampleApp({super.key});
@override
State<EditableTextToolbarBuilderExampleApp> createState() =>
_EditableTextToolbarBuilderExampleAppState();
}
class _EditableTextToolbarBuilderExampleAppState
extends State<EditableTextToolbarBuilderExampleApp> {
final TextEditingController _controller = TextEditingController(
text:
'Right click (desktop) or long press (mobile) to see the menu with a custom toolbar.',
);
@override
void initState() {
super.initState();
// On web, disable the browser's context menu since this example uses a custom
// Flutter-rendered context menu.
if (kIsWeb) {
BrowserContextMenu.disableContextMenu();
}
}
@override
void dispose() {
if (kIsWeb) {
BrowserContextMenu.enableContextMenu();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Custom toolbar, default-looking buttons'),
),
body: Center(
child: Column(
children: <Widget>[
const SizedBox(height: 20.0),
TextField(
controller: _controller,
contextMenuBuilder:
(
BuildContext context,
EditableTextState editableTextState,
) {
return _MyTextSelectionToolbar(
anchor:
editableTextState.contextMenuAnchors.primaryAnchor,
// getAdaptiveButtons creates the default button widgets for
// the current platform.
children:
AdaptiveTextSelectionToolbar.getAdaptiveButtons(
context,
// These buttons just close the menu when clicked.
<ContextMenuButtonItem>[
ContextMenuButtonItem(
label: 'One',
onPressed: () =>
ContextMenuController.removeAny(),
),
ContextMenuButtonItem(
label: 'Two',
onPressed: () =>
ContextMenuController.removeAny(),
),
ContextMenuButtonItem(
label: 'Three',
onPressed: () =>
ContextMenuController.removeAny(),
),
ContextMenuButtonItem(
label: 'Four',
onPressed: () =>
ContextMenuController.removeAny(),
),
ContextMenuButtonItem(
label: 'Five',
onPressed: () =>
ContextMenuController.removeAny(),
),
],
).toList(),
);
},
),
],
),
),
),
);
}
}
/// A simple, yet totally custom, text selection toolbar.
///
/// Displays its children in a scrollable grid.
class _MyTextSelectionToolbar extends StatelessWidget {
const _MyTextSelectionToolbar({required this.anchor, required this.children});
final Offset anchor;
final List<Widget> children;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
top: anchor.dy,
left: anchor.dx,
child: Container(
width: 200.0,
height: 200.0,
color: Colors.cyanAccent.withValues(alpha: 0.5),
child: GridView.count(
padding: const .all(12.0),
crossAxisCount: 2,
children: children,
),
),
),
],
);
}
}
See also:
CupertinoAdaptiveTextSelectionToolbar.getAdaptiveButtons, which is the Cupertino equivalent of this class and builds only the Cupertino buttons.
Implementation
// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/context_menu/editable_text_toolbar_builder.2.dart#body}
///
/// </callout-box>
///
/// See also:
///
/// * [CupertinoAdaptiveTextSelectionToolbar.getAdaptiveButtons], which is the
/// Cupertino equivalent of this class and builds only the Cupertino
/// buttons.
static Iterable<Widget> getAdaptiveButtons(
BuildContext context,
List<ContextMenuButtonItem> buttonItems,
) {
switch (Theme.of(context).platform) {
case TargetPlatform.iOS:
return buttonItems.map((ContextMenuButtonItem buttonItem) {
return CupertinoTextSelectionToolbarButton.buttonItem(buttonItem: buttonItem);
});
case TargetPlatform.fuchsia:
case TargetPlatform.android:
final buttons = <Widget>[];
for (var i = 0; i < buttonItems.length; i++) {
final ContextMenuButtonItem buttonItem = buttonItems[i];
buttons.add(
TextSelectionToolbarTextButton(
padding: TextSelectionToolbarTextButton.getPadding(i, buttonItems.length),
onPressed: buttonItem.onPressed,
alignment: AlignmentDirectional.centerStart,
child: Text(getButtonLabel(context, buttonItem)),
),
);
}
return buttons;
case TargetPlatform.linux:
case TargetPlatform.windows:
return buttonItems.map((ContextMenuButtonItem buttonItem) {
return DesktopTextSelectionToolbarButton.text(
context: context,
onPressed: buttonItem.onPressed,
text: getButtonLabel(context, buttonItem),
);
});
case TargetPlatform.macOS:
return buttonItems.map((ContextMenuButtonItem buttonItem) {
return CupertinoDesktopTextSelectionToolbarButton.text(
onPressed: buttonItem.onPressed,
text: getButtonLabel(context, buttonItem),
);
});
}
}