可选择的包是一个 Flutter 小部件,可增强所有包含文本小部件中的文本选择功能。它包装文本元素以实现无缝且一致的文本选择行为,非常适合需要交互式文本内容的应用程序,如文档、笔记或阅读界面。该包可在所有主要平台——Android、iOS、Web、macOS、Windows 和 Linux 上运行,确保功能统一。它简化了可选择文本的实现,无需复杂的自定义逻辑。专为希望使用单一、可重用的包装器轻松为多个文本组件添加选择功能的开发者设计。
适合场景
阅读应用
文档编辑器
记事工具
交互式教程
文本共享功能
主要特点
通用文本选择
跨平台支持
多个文本的单一包装
简单集成
一致的选择行为
适合对象
开发文本密集型应用的开发者
需要多文本选择的应用
具有跨平台需求的项目
专注于可读性的UI
教育类或内容丰富的应用程序
使用建议
可能需要额外的样式来自定义选择手柄
仅限文本选择
不适用于非文本控件
大文本块的性能影响
依赖于底层平台的文本渲染
原始 README
以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。
selectable
A Flutter widget that enables text selection over all the text widgets it
contains — with platform-adaptive selection handles and popup menu, a
controller for listening to and programmatically changing the selection, and
customizable menu items, selection color, and selection rendering.
Note: This library predates Flutter's
SelectableRegion
and related classes. It continues to be maintained because it is used in
production apps, but if Flutter's native selection support meets your
needs, consider using it instead.
Features
Selection across all the text widgets contained in a Selectable —
multiple Text and RichText widgets, spanning paragraphs.
Long-press (and optionally double-tap) a word to select it, then drag the
selection handles to adjust the selection, with autoscroll when dragging
near the top or bottom of a scrollable viewport.
Platform-adaptive selection controls and popup menu: Cupertino style on
iOS and macOS, Material style elsewhere.
A default popup menu with Copy, Look Up, and Search Web items — localized
using the ambient MaterialLocalizations/CupertinoLocalizations — and
support for replacing or extending the menu with custom items.
A SelectableController for listening to selection changes and for
programmatically selecting, deselecting, hiding, and showing the
selection.
Customizable selection appearance via selectionColor, selection rect
"rectifiers", and fully custom selection painters.
IgnoreSelectable for excluding subtrees from selection.
Getting started
Add selectable to your app's pubspec.yaml file:
dependencies:selectable:^0.7.0
Requires Dart >=3.12.0 and Flutter >=3.44.0.
Material and Cupertino packages
As of 0.7.0, selectable uses the standalone material_ui and cupertino_ui packages instead of Flutter's in-framework material.dart and cupertino.dart libraries, which are moving out of the SDK (see Flutter's migration guide).
Your own code does not need to change, because selectable's public API exposes no Material or Cupertino types. The popup menu, however, gets its theme and its localized labels from material_ui and cupertino_ui, so your app has to provide them. If your app has migrated to those packages, this works as-is. If your app still imports package:flutter/material.dart, the popup menu throws No MaterialLocalizations found.
If your app has not migrated yet, you can stay on the 0.6.x line, which continues to use Flutter's in-framework libraries:
dependencies:selectable:^0.6.7
Or you can provide material_ui's theme and localizations around your Selectable:
import'package:material_ui/material_ui.dart'as mui;
Localizations(
locale: Localizations.localeOf(context),
delegates: mui.GlobalMaterialLocalizations.delegates,
child: mui.Theme(
// Configure this to match your app's theme.
data: mui.ThemeData(),
child: Selectable(child: myContent),
),
)
Note that MaterialUiCompatibilityBridge does not help here: it maps a migrated app's theme back to the in-framework libraries, which is the opposite direction.
Usage
Import the package:
import'package:selectable/selectable.dart';
And wrap the widgets you want to enable text selection for in a
Selectable:
Scaffold(
body: SingleChildScrollView(
child: Selectable(
child: Column(
children: [
Text('... a lot of text ...'),
// ... more widgets of any type that might contain text ...
],
),
),
),
)
Important: If a scrollable widget (such as SingleChildScrollView,
ListView, or CustomScrollView) is used to wrap the text widgets you
want to enable selection for, the Selectable widget must be a
descendant of the scrollable widget and an ancestor of the text
widgets.
Scrollables and app bars
If the Selectable is in a scrollable, pass the scrollable's
ScrollController to the Selectable as well. It is used to autoscroll
when a selection handle is dragged near the top or bottom of the viewport,
and to keep the popup menu positioned in the visible area. If part of the
viewport is covered by an overlay, such as a pinned app bar, set
topOverlayHeight to its height:
Wrap widgets that shouldn't be selectable in IgnoreSelectable:
IgnoreSelectable(
child: Text('This text is not selectable.'),
)
Customizing the popup menu
Selectable shows a popup menu with Copy, Look Up, and Search Web items by
default. The default item titles are localized using the ambient
MaterialLocalizations (or CupertinoLocalizations). To customize the
menu, pass in popupMenuItems. For example, to show the default Copy item
along with a custom item that shows the selected text in a dialog:
Menu items can also have an icon, and custom menu builders can resolve
the localized default title for a built-in item type with
defaultTitleForMenuItemType.
Using a SelectableController
Pass a SelectableController to the Selectable to listen to selection
changes and to work with the selection programmatically:
final _selectionController = SelectableController();
// In the widget tree:Selectable(
selectionController: _selectionController,
child: child,
)
// Listen for selection changes.
_selectionController.addListener(() {
if (_selectionController.isTextSelected) {
print('Selected text: ${_selectionController.getSelection()!.text}');
}
});
The controller supports, among other things:
// Select programmatically.
_selectionController.selectAll();
_selectionController.selectWordAtIndex(100);
_selectionController.selectWordsBetweenIndexes(100, 200);
// Deselect.
_selectionController.deselect();
// Hide and show the selection (e.g. while a dialog is showing),// with an optional fade animation duration.
_selectionController.hide();
_selectionController.unhide();
// Get the combined text of all the text widgets contained in the// Selectable (useful with the index-based select methods above), or// just its length.final text = _selectionController.getContainedText();
final length = _selectionController.containedTextLength;
The Selection object returned by getSelection() includes the selected
text, the global startIndex and endIndex of the selection, and the
selection rectangles. Remember to dispose the controller when it is no
longer needed.
Customizing the selection appearance
The selection color can be set with the selectionColor parameter. How the
raw rectangles of selected text are converted into the displayed selection
rects can be customized with a "rectifier" — for example, to merge the
per-line rects into, at most, three contiguous rects:
or provide your own List<Rect> Function(List<Rect>). For full control
over how the selection is drawn, implement a custom SelectionPainter and
set it with _selectionController.setCustomPainter (see
example/lib/my_selection_painter.dart).
Additional information
The example app
demonstrates most of these features, including advanced use cases such as
updating the style of the selected text spans.