Unverified Commit bef97630 authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

Add Share button to the SelectableRegion toolbar on Android (#141447)

## Description

This PR adds the share button to text selection toolbar buttons on Android ~~and iOS~~ for `SelectableRegion` (and therefore `SelectionArea`).

https://github.com/flutter/flutter/pull/139479 adds this button for `EditableText` (which is used by `TextField` and `SelectableText` but not by `SelectionArea`).

**Edit**: supporting this on iOS will need more work (see https://github.com/flutter/flutter/pull/141447#issuecomment-1889942622 and https://github.com/flutter/flutter/issues/141775).

## Related Issue

Follow up for https://github.com/flutter/flutter/issues/138728

## Tests

Adds 1 test.
parent 63018fe6
...@@ -152,6 +152,7 @@ class CupertinoAdaptiveTextSelectionToolbar extends StatelessWidget { ...@@ -152,6 +152,7 @@ class CupertinoAdaptiveTextSelectionToolbar extends StatelessWidget {
selectionGeometry: selectionGeometry, selectionGeometry: selectionGeometry,
onCopy: onCopy, onCopy: onCopy,
onSelectAll: onSelectAll, onSelectAll: onSelectAll,
onShare: null, // See https://github.com/flutter/flutter/issues/141775.
); );
/// {@macro flutter.material.AdaptiveTextSelectionToolbar.anchors} /// {@macro flutter.material.AdaptiveTextSelectionToolbar.anchors}
......
...@@ -150,6 +150,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget { ...@@ -150,6 +150,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
super.key, super.key,
required VoidCallback onCopy, required VoidCallback onCopy,
required VoidCallback onSelectAll, required VoidCallback onSelectAll,
required VoidCallback? onShare,
required SelectionGeometry selectionGeometry, required SelectionGeometry selectionGeometry,
required this.anchors, required this.anchors,
}) : children = null, }) : children = null,
...@@ -157,6 +158,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget { ...@@ -157,6 +158,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
selectionGeometry: selectionGeometry, selectionGeometry: selectionGeometry,
onCopy: onCopy, onCopy: onCopy,
onSelectAll: onSelectAll, onSelectAll: onSelectAll,
onShare: onShare,
); );
/// Create an instance of [AdaptiveTextSelectionToolbar] with the default /// Create an instance of [AdaptiveTextSelectionToolbar] with the default
......
...@@ -267,9 +267,29 @@ class SelectableRegion extends StatefulWidget { ...@@ -267,9 +267,29 @@ class SelectableRegion extends StatefulWidget {
required final SelectionGeometry selectionGeometry, required final SelectionGeometry selectionGeometry,
required final VoidCallback onCopy, required final VoidCallback onCopy,
required final VoidCallback onSelectAll, required final VoidCallback onSelectAll,
required final VoidCallback? onShare,
}) { }) {
final bool canCopy = selectionGeometry.status == SelectionStatus.uncollapsed; final bool canCopy = selectionGeometry.status == SelectionStatus.uncollapsed;
final bool canSelectAll = selectionGeometry.hasContent; final bool canSelectAll = selectionGeometry.hasContent;
final bool platformCanShare = switch (defaultTargetPlatform) {
TargetPlatform.android
=> selectionGeometry.status == SelectionStatus.uncollapsed,
TargetPlatform.macOS
|| TargetPlatform.fuchsia
|| TargetPlatform.linux
|| TargetPlatform.windows
=> false,
// TODO(bleroux): the share button should be shown on iOS but the share
// functionality requires some changes on the engine side because, on iPad,
// it needs an anchor for the popup.
// See: https://github.com/flutter/flutter/issues/141775.
TargetPlatform.iOS
=> false,
};
final bool canShare = onShare != null && platformCanShare;
// On Android, the share button is before the select all button.
final bool showShareBeforeSelectAll = defaultTargetPlatform == TargetPlatform.android;
// Determine which buttons will appear so that the order and total number is // Determine which buttons will appear so that the order and total number is
// known. A button's position in the menu can slightly affect its // known. A button's position in the menu can slightly affect its
...@@ -280,11 +300,21 @@ class SelectableRegion extends StatefulWidget { ...@@ -280,11 +300,21 @@ class SelectableRegion extends StatefulWidget {
onPressed: onCopy, onPressed: onCopy,
type: ContextMenuButtonType.copy, type: ContextMenuButtonType.copy,
), ),
if (canShare && showShareBeforeSelectAll)
ContextMenuButtonItem(
onPressed: onShare,
type: ContextMenuButtonType.share,
),
if (canSelectAll) if (canSelectAll)
ContextMenuButtonItem( ContextMenuButtonItem(
onPressed: onSelectAll, onPressed: onSelectAll,
type: ContextMenuButtonType.selectAll, type: ContextMenuButtonType.selectAll,
), ),
if (canShare && !showShareBeforeSelectAll)
ContextMenuButtonItem(
onPressed: onShare,
type: ContextMenuButtonType.share,
),
]; ];
} }
...@@ -1089,6 +1119,14 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe ...@@ -1089,6 +1119,14 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
await Clipboard.setData(ClipboardData(text: data.plainText)); await Clipboard.setData(ClipboardData(text: data.plainText));
} }
Future<void> _share() async {
final SelectedContent? data = _selectable?.getSelectedContent();
if (data == null) {
return;
}
await SystemChannels.platform.invokeMethod('Share.invoke', data.plainText);
}
/// {@macro flutter.widgets.EditableText.getAnchors} /// {@macro flutter.widgets.EditableText.getAnchors}
/// ///
/// See also: /// See also:
...@@ -1191,7 +1229,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe ...@@ -1191,7 +1229,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
onCopy: () { onCopy: () {
_copy(); _copy();
// In Android copy should clear the selection. // On Android copy should clear the selection.
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
case TargetPlatform.android: case TargetPlatform.android:
case TargetPlatform.fuchsia: case TargetPlatform.fuchsia:
...@@ -1217,6 +1255,22 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe ...@@ -1217,6 +1255,22 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
hideToolbar(); hideToolbar();
} }
}, },
onShare: () {
_share();
// On Android, share should clear the selection.
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
_clearSelection();
case TargetPlatform.iOS:
hideToolbar(false);
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
hideToolbar();
}
},
)..addAll(_textProcessingActionButtonItems); )..addAll(_textProcessingActionButtonItems);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment