Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
2338576a
Unverified
Commit
2338576a
authored
Jul 19, 2019
by
chunhtai
Committed by
GitHub
Jul 19, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement selectable text (#34019)
parent
41bc10fa
Changes
8
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
4461 additions
and
55 deletions
+4461
-55
material.dart
packages/flutter/lib/material.dart
+1
-0
selectable_text.dart
packages/flutter/lib/src/material/selectable_text.dart
+580
-0
text_field.dart
packages/flutter/lib/src/material/text_field.dart
+2
-8
text_painter.dart
packages/flutter/lib/src/painting/text_painter.dart
+2
-2
editable.dart
packages/flutter/lib/src/rendering/editable.dart
+65
-24
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+64
-20
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+25
-1
selectable_text_test.dart
packages/flutter/test/widgets/selectable_text_test.dart
+3722
-0
No files found.
packages/flutter/lib/material.dart
View file @
2338576a
...
...
@@ -93,6 +93,7 @@ export 'src/material/reorderable_list.dart';
export
'src/material/scaffold.dart'
;
export
'src/material/scrollbar.dart'
;
export
'src/material/search.dart'
;
export
'src/material/selectable_text.dart'
;
export
'src/material/shadows.dart'
;
export
'src/material/slider.dart'
;
export
'src/material/slider_theme.dart'
;
...
...
packages/flutter/lib/src/material/selectable_text.dart
0 → 100644
View file @
2338576a
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/material/text_field.dart
View file @
2338576a
...
...
@@ -17,6 +17,7 @@ import 'ink_well.dart' show InteractiveInkFeature;
import
'input_decorator.dart'
;
import
'material.dart'
;
import
'material_localizations.dart'
;
import
'selectable_text.dart'
show
iOSHorizontalOffset
;
import
'text_selection.dart'
;
import
'theme.dart'
;
...
...
@@ -932,14 +933,7 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
cursorOpacityAnimates
=
true
;
cursorColor
??=
CupertinoTheme
.
of
(
context
).
primaryColor
;
cursorRadius
??=
const
Radius
.
circular
(
2.0
);
// An eyeballed value that moves the cursor slightly left of where it is
// rendered for text on Android so its positioning more accurately matches the
// native iOS text cursor positioning.
//
// This value is in device pixels, not logical pixels as is typically used
// throughout the codebase.
const
int
_iOSHorizontalOffset
=
-
2
;
cursorOffset
=
Offset
(
_iOSHorizontalOffset
/
MediaQuery
.
of
(
context
).
devicePixelRatio
,
0
);
cursorOffset
=
Offset
(
iOSHorizontalOffset
/
MediaQuery
.
of
(
context
).
devicePixelRatio
,
0
);
break
;
case
TargetPlatform
.
android
:
...
...
packages/flutter/lib/src/painting/text_painter.dart
View file @
2338576a
...
...
@@ -652,7 +652,7 @@ class TextPainter {
final
double
caretEnd
=
box
.
end
;
final
double
dx
=
box
.
direction
==
TextDirection
.
rtl
?
caretEnd
-
caretPrototype
.
width
:
caretEnd
;
return
Rect
.
fromLTRB
(
min
(
dx
,
width
),
box
.
top
,
min
(
dx
,
width
),
box
.
bottom
);
return
Rect
.
fromLTRB
(
min
(
dx
,
_paragraph
.
width
),
box
.
top
,
min
(
dx
,
_paragraph
.
width
),
box
.
bottom
);
}
return
null
;
}
...
...
@@ -694,7 +694,7 @@ class TextPainter {
final
TextBox
box
=
boxes
.
last
;
final
double
caretStart
=
box
.
start
;
final
double
dx
=
box
.
direction
==
TextDirection
.
rtl
?
caretStart
-
caretPrototype
.
width
:
caretStart
;
return
Rect
.
fromLTRB
(
min
(
dx
,
width
),
box
.
top
,
min
(
dx
,
width
),
box
.
bottom
);
return
Rect
.
fromLTRB
(
min
(
dx
,
_paragraph
.
width
),
box
.
top
,
min
(
dx
,
_paragraph
.
width
),
box
.
bottom
);
}
return
null
;
}
...
...
packages/flutter/lib/src/rendering/editable.dart
View file @
2338576a
...
...
@@ -157,6 +157,9 @@ class RenderEditable extends RenderBox {
this
.
onSelectionChanged
,
this
.
onCaretChanged
,
this
.
ignorePointer
=
false
,
bool
readOnly
=
false
,
bool
forceLine
=
true
,
TextWidthBasis
textWidthBasis
=
TextWidthBasis
.
parent
,
bool
obscureText
=
false
,
Locale
locale
,
double
cursorWidth
=
1.0
,
...
...
@@ -185,10 +188,13 @@ class RenderEditable extends RenderBox {
assert
(
textScaleFactor
!=
null
),
assert
(
offset
!=
null
),
assert
(
ignorePointer
!=
null
),
assert
(
textWidthBasis
!=
null
),
assert
(
paintCursorAboveText
!=
null
),
assert
(
obscureText
!=
null
),
assert
(
textSelectionDelegate
!=
null
),
assert
(
cursorWidth
!=
null
&&
cursorWidth
>=
0.0
),
assert
(
readOnly
!=
null
),
assert
(
forceLine
!=
null
),
assert
(
devicePixelRatio
!=
null
),
_textPainter
=
TextPainter
(
text:
text
,
...
...
@@ -197,6 +203,7 @@ class RenderEditable extends RenderBox {
textScaleFactor:
textScaleFactor
,
locale:
locale
,
strutStyle:
strutStyle
,
textWidthBasis:
textWidthBasis
,
),
_cursorColor
=
cursorColor
,
_backgroundCursorColor
=
backgroundCursorColor
,
...
...
@@ -216,7 +223,9 @@ class RenderEditable extends RenderBox {
_devicePixelRatio
=
devicePixelRatio
,
_startHandleLayerLink
=
startHandleLayerLink
,
_endHandleLayerLink
=
endHandleLayerLink
,
_obscureText
=
obscureText
{
_obscureText
=
obscureText
,
_readOnly
=
readOnly
,
_forceLine
=
forceLine
{
assert
(
_showCursor
!=
null
);
assert
(!
_showCursor
.
value
||
cursorColor
!=
null
);
this
.
hasFocus
=
hasFocus
??
false
;
...
...
@@ -245,12 +254,15 @@ class RenderEditable extends RenderBox {
/// The default value of this property is false.
bool
ignorePointer
;
/// Whether text is composed.
///
/// Text is composed when user selects it for editing. The [TextSpan] will have
/// children with composing effect and leave text property to be null.
@visibleForTesting
bool
get
isComposingText
=>
text
.
text
==
null
;
/// {@macro flutter.widgets.text.DefaultTextStyle.textWidthBasis}
TextWidthBasis
get
textWidthBasis
=>
_textPainter
.
textWidthBasis
;
set
textWidthBasis
(
TextWidthBasis
value
)
{
assert
(
value
!=
null
);
if
(
_textPainter
.
textWidthBasis
==
value
)
return
;
_textPainter
.
textWidthBasis
=
value
;
markNeedsTextLayout
();
}
/// The pixel ratio of the current device.
///
...
...
@@ -444,7 +456,7 @@ class RenderEditable extends RenderBox {
if
(
leftArrow
&&
_extentOffset
>
2
)
{
final
TextSelection
textSelection
=
_selectWordAtOffset
(
TextPosition
(
offset:
_extentOffset
-
2
));
newOffset
=
textSelection
.
baseOffset
+
1
;
}
else
if
(
rightArrow
&&
_extentOffset
<
text
.
t
ext
.
length
-
2
)
{
}
else
if
(
rightArrow
&&
_extentOffset
<
text
.
t
oPlainText
()
.
length
-
2
)
{
final
TextSelection
textSelection
=
_selectWordAtOffset
(
TextPosition
(
offset:
_extentOffset
+
1
));
newOffset
=
textSelection
.
extentOffset
-
1
;
}
...
...
@@ -487,7 +499,7 @@ class RenderEditable extends RenderBox {
// case that the user wants to unhighlight some text.
if
(
position
.
offset
==
_extentOffset
)
{
if
(
downArrow
)
newOffset
=
text
.
t
ext
.
length
;
newOffset
=
text
.
t
oPlainText
()
.
length
;
else
if
(
upArrow
)
newOffset
=
0
;
_resetCursor
=
shift
;
...
...
@@ -554,16 +566,16 @@ class RenderEditable extends RenderBox {
case
_kCKeyCode:
if
(!
selection
.
isCollapsed
)
{
Clipboard
.
setData
(
ClipboardData
(
text:
selection
.
textInside
(
text
.
t
ext
)));
ClipboardData
(
text:
selection
.
textInside
(
text
.
t
oPlainText
()
)));
}
break
;
case
_kXKeyCode:
if
(!
selection
.
isCollapsed
)
{
Clipboard
.
setData
(
ClipboardData
(
text:
selection
.
textInside
(
text
.
t
ext
)));
ClipboardData
(
text:
selection
.
textInside
(
text
.
t
oPlainText
()
)));
textSelectionDelegate
.
textEditingValue
=
TextEditingValue
(
text:
selection
.
textBefore
(
text
.
t
ext
)
+
selection
.
textAfter
(
text
.
t
ext
),
text:
selection
.
textBefore
(
text
.
t
oPlainText
()
)
+
selection
.
textAfter
(
text
.
t
oPlainText
()
),
selection:
TextSelection
.
collapsed
(
offset:
selection
.
start
),
);
}
...
...
@@ -601,15 +613,15 @@ class RenderEditable extends RenderBox {
}
void
_handleDelete
()
{
if
(
selection
.
textAfter
(
text
.
t
ext
).
isNotEmpty
)
{
if
(
selection
.
textAfter
(
text
.
t
oPlainText
()
).
isNotEmpty
)
{
textSelectionDelegate
.
textEditingValue
=
TextEditingValue
(
text:
selection
.
textBefore
(
text
.
t
ext
)
+
selection
.
textAfter
(
text
.
t
ext
).
substring
(
1
),
text:
selection
.
textBefore
(
text
.
t
oPlainText
()
)
+
selection
.
textAfter
(
text
.
t
oPlainText
()
).
substring
(
1
),
selection:
TextSelection
.
collapsed
(
offset:
selection
.
start
),
);
}
else
{
textSelectionDelegate
.
textEditingValue
=
TextEditingValue
(
text:
selection
.
textBefore
(
text
.
t
ext
),
text:
selection
.
textBefore
(
text
.
t
oPlainText
()
),
selection:
TextSelection
.
collapsed
(
offset:
selection
.
start
),
);
}
...
...
@@ -758,6 +770,28 @@ class RenderEditable extends RenderBox {
markNeedsSemanticsUpdate
();
}
/// Whether this rendering object will take a full line regardless the text width.
bool
get
forceLine
=>
_forceLine
;
bool
_forceLine
=
false
;
set
forceLine
(
bool
value
)
{
assert
(
value
!=
null
);
if
(
_forceLine
==
value
)
return
;
_forceLine
=
value
;
markNeedsLayout
();
}
/// Whether this rendering object is read only.
bool
get
readOnly
=>
_readOnly
;
bool
_readOnly
=
false
;
set
readOnly
(
bool
value
)
{
assert
(
value
!=
null
);
if
(
_readOnly
==
value
)
return
;
_readOnly
=
value
;
markNeedsSemanticsUpdate
();
}
/// The maximum number of lines for the text to span, wrapping if necessary.
///
/// If this is 1 (the default), the text will not wrap, but will extend
...
...
@@ -983,6 +1017,8 @@ class RenderEditable extends RenderBox {
return
enableInteractiveSelection
??
!
obscureText
;
}
double
get
_caretMargin
=>
_kCaretGap
+
cursorWidth
;
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
...
...
@@ -995,7 +1031,8 @@ class RenderEditable extends RenderBox {
..
isMultiline
=
_isMultiline
..
textDirection
=
textDirection
..
isFocused
=
hasFocus
..
isTextField
=
true
;
..
isTextField
=
true
..
isReadOnly
=
readOnly
;
if
(
hasFocus
&&
selectionEnabled
)
config
.
onSetSelection
=
_handleSetSelection
;
...
...
@@ -1526,10 +1563,12 @@ class RenderEditable extends RenderBox {
assert
(
constraintWidth
!=
null
);
if
(
_textLayoutLastWidth
==
constraintWidth
)
return
;
final
double
caretMargin
=
_kCaretGap
+
cursorWidth
;
final
double
availableWidth
=
math
.
max
(
0.0
,
constraintWidth
-
caretMargin
);
final
double
availableWidth
=
math
.
max
(
0.0
,
constraintWidth
-
_caretMargin
);
final
double
maxWidth
=
_isMultiline
?
availableWidth
:
double
.
infinity
;
_textPainter
.
layout
(
minWidth:
availableWidth
,
maxWidth:
maxWidth
);
_textPainter
.
layout
(
minWidth:
forceLine
?
availableWidth
:
0
,
maxWidth:
maxWidth
,
);
_textLayoutLastWidth
=
constraintWidth
;
}
...
...
@@ -1566,8 +1605,10 @@ class RenderEditable extends RenderBox {
// though we currently don't use those here.
// See also RenderParagraph which has a similar issue.
final
Size
textPainterSize
=
_textPainter
.
size
;
size
=
Size
(
constraints
.
maxWidth
,
constraints
.
constrainHeight
(
_preferredHeight
(
constraints
.
maxWidth
)));
final
Size
contentSize
=
Size
(
textPainterSize
.
width
+
_kCaretGap
+
cursorWidth
,
textPainterSize
.
height
);
final
double
width
=
forceLine
?
constraints
.
maxWidth
:
constraints
.
constrainWidth
(
_textPainter
.
size
.
width
+
_caretMargin
);
size
=
Size
(
width
,
constraints
.
constrainHeight
(
_preferredHeight
(
constraints
.
maxWidth
)));
final
Size
contentSize
=
Size
(
textPainterSize
.
width
+
_caretMargin
,
textPainterSize
.
height
);
_maxScrollExtent
=
_getMaxScrollExtent
(
contentSize
);
offset
.
applyViewportDimension
(
_viewportExtent
);
offset
.
applyContentDimensions
(
0.0
,
_maxScrollExtent
);
...
...
packages/flutter/lib/src/widgets/editable_text.dart
View file @
2338576a
...
...
@@ -150,6 +150,29 @@ class TextEditingController extends ValueNotifier<TextEditingValue> {
);
}
/// Builds [TextSpan] from current editing value.
///
/// By default makes text in composing range appear as underlined.
/// Descendants can override this method to customize appearance of text.
TextSpan
buildTextSpan
({
TextStyle
style
,
bool
withComposing
})
{
if
(!
value
.
composing
.
isValid
||
!
withComposing
)
{
return
TextSpan
(
style:
style
,
text:
text
);
}
final
TextStyle
composingStyle
=
style
.
merge
(
const
TextStyle
(
decoration:
TextDecoration
.
underline
),
);
return
TextSpan
(
style:
style
,
children:
<
TextSpan
>[
TextSpan
(
text:
value
.
composing
.
textBefore
(
value
.
text
)),
TextSpan
(
style:
composingStyle
,
text:
value
.
composing
.
textInside
(
value
.
text
),
),
TextSpan
(
text:
value
.
composing
.
textAfter
(
value
.
text
)),
]);
}
/// The currently selected [text].
///
/// If the selection is collapsed, then this property gives the offset of the
...
...
@@ -288,6 +311,8 @@ class EditableText extends StatefulWidget {
this
.
maxLines
=
1
,
this
.
minLines
,
this
.
expands
=
false
,
this
.
forceLine
=
true
,
this
.
textWidthBasis
=
TextWidthBasis
.
parent
,
this
.
autofocus
=
false
,
bool
showCursor
,
this
.
showSelectionHandles
=
false
,
...
...
@@ -320,6 +345,7 @@ class EditableText extends StatefulWidget {
assert
(
autocorrect
!=
null
),
assert
(
showSelectionHandles
!=
null
),
assert
(
readOnly
!=
null
),
assert
(
forceLine
!=
null
),
assert
(
style
!=
null
),
assert
(
cursorColor
!=
null
),
assert
(
cursorOpacityAnimates
!=
null
),
...
...
@@ -368,6 +394,9 @@ class EditableText extends StatefulWidget {
/// {@endtemplate}
final
bool
obscureText
;
/// {@macro flutter.widgets.text.DefaultTextStyle.textWidthBasis}
final
TextWidthBasis
textWidthBasis
;
/// {@template flutter.widgets.editableText.readOnly}
/// Whether the text can be changed.
///
...
...
@@ -378,6 +407,18 @@ class EditableText extends StatefulWidget {
/// {@endtemplate}
final
bool
readOnly
;
/// Whether the text will take the full width regardless of the text width.
///
/// When this is set to false, the width will be based on text width, which
/// will also be affected by [textWidthBasis].
///
/// Defaults to true. Must not be null.
///
/// See also:
///
/// * [textWidthBasis], which controls the calculation of text width.
final
bool
forceLine
;
/// Whether to show selection handles.
///
/// When a selection is active, there will be two handles at each side of
...
...
@@ -396,7 +437,7 @@ class EditableText extends StatefulWidget {
///
/// See also:
///
/// * [showSelectionHandles], which controls the visibility of the selection handles.
.
/// * [showSelectionHandles], which controls the visibility of the selection handles.
/// {@endtemplate}
final
bool
showCursor
;
...
...
@@ -1622,6 +1663,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
showCursor:
EditableText
.
debugDeterministicCursor
?
ValueNotifier
<
bool
>(
widget
.
showCursor
)
:
_cursorVisibilityNotifier
,
forceLine:
widget
.
forceLine
,
readOnly:
widget
.
readOnly
,
hasFocus:
_hasFocus
,
maxLines:
widget
.
maxLines
,
minLines:
widget
.
minLines
,
...
...
@@ -1632,6 +1675,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
textAlign:
widget
.
textAlign
,
textDirection:
_textDirection
,
locale:
widget
.
locale
,
textWidthBasis:
widget
.
textWidthBasis
,
obscureText:
widget
.
obscureText
,
autocorrect:
widget
.
autocorrect
,
offset:
offset
,
...
...
@@ -1657,33 +1701,21 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
/// By default makes text in composing range appear as underlined.
/// Descendants can override this method to customize appearance of text.
TextSpan
buildTextSpan
()
{
// Read only mode should not paint text composing.
if
(!
widget
.
obscureText
&&
_value
.
composing
.
isValid
&&
!
widget
.
readOnly
)
{
final
TextStyle
composingStyle
=
widget
.
style
.
merge
(
const
TextStyle
(
decoration:
TextDecoration
.
underline
),
);
return
TextSpan
(
style:
widget
.
style
,
children:
<
TextSpan
>[
TextSpan
(
text:
_value
.
composing
.
textBefore
(
_value
.
text
)),
TextSpan
(
style:
composingStyle
,
text:
_value
.
composing
.
textInside
(
_value
.
text
),
),
TextSpan
(
text:
_value
.
composing
.
textAfter
(
_value
.
text
)),
]);
}
String
text
=
_value
.
text
;
if
(
widget
.
obscureText
)
{
String
text
=
_value
.
text
;
text
=
RenderEditable
.
obscuringCharacter
*
text
.
length
;
final
int
o
=
_obscureShowCharTicksPending
>
0
?
_obscureLatestCharIndex
:
null
;
if
(
o
!=
null
&&
o
>=
0
&&
o
<
text
.
length
)
text
=
text
.
replaceRange
(
o
,
o
+
1
,
_value
.
text
.
substring
(
o
,
o
+
1
));
}
return
TextSpan
(
style:
widget
.
style
,
text:
text
);
}
// Read only mode should not paint text composing.
return
widget
.
controller
.
buildTextSpan
(
style:
widget
.
style
,
withComposing:
!
widget
.
readOnly
,
);
}
}
class
_Editable
extends
LeafRenderObjectWidget
{
...
...
@@ -1696,6 +1728,9 @@ class _Editable extends LeafRenderObjectWidget {
this
.
cursorColor
,
this
.
backgroundCursorColor
,
this
.
showCursor
,
this
.
forceLine
,
this
.
readOnly
,
this
.
textWidthBasis
,
this
.
hasFocus
,
this
.
maxLines
,
this
.
minLines
,
...
...
@@ -1730,6 +1765,8 @@ class _Editable extends LeafRenderObjectWidget {
final
LayerLink
endHandleLayerLink
;
final
Color
backgroundCursorColor
;
final
ValueNotifier
<
bool
>
showCursor
;
final
bool
forceLine
;
final
bool
readOnly
;
final
bool
hasFocus
;
final
int
maxLines
;
final
int
minLines
;
...
...
@@ -1741,6 +1778,7 @@ class _Editable extends LeafRenderObjectWidget {
final
TextDirection
textDirection
;
final
Locale
locale
;
final
bool
obscureText
;
final
TextWidthBasis
textWidthBasis
;
final
bool
autocorrect
;
final
ViewportOffset
offset
;
final
SelectionChangedHandler
onSelectionChanged
;
...
...
@@ -1763,6 +1801,8 @@ class _Editable extends LeafRenderObjectWidget {
endHandleLayerLink:
endHandleLayerLink
,
backgroundCursorColor:
backgroundCursorColor
,
showCursor:
showCursor
,
forceLine:
forceLine
,
readOnly:
readOnly
,
hasFocus:
hasFocus
,
maxLines:
maxLines
,
minLines:
minLines
,
...
...
@@ -1779,6 +1819,7 @@ class _Editable extends LeafRenderObjectWidget {
onCaretChanged:
onCaretChanged
,
ignorePointer:
rendererIgnoresPointer
,
obscureText:
obscureText
,
textWidthBasis:
textWidthBasis
,
cursorWidth:
cursorWidth
,
cursorRadius:
cursorRadius
,
cursorOffset:
cursorOffset
,
...
...
@@ -1797,6 +1838,8 @@ class _Editable extends LeafRenderObjectWidget {
..
startHandleLayerLink
=
startHandleLayerLink
..
endHandleLayerLink
=
endHandleLayerLink
..
showCursor
=
showCursor
..
forceLine
=
forceLine
..
readOnly
=
readOnly
..
hasFocus
=
hasFocus
..
maxLines
=
maxLines
..
minLines
=
minLines
...
...
@@ -1812,6 +1855,7 @@ class _Editable extends LeafRenderObjectWidget {
..
onSelectionChanged
=
onSelectionChanged
..
onCaretChanged
=
onCaretChanged
..
ignorePointer
=
rendererIgnoresPointer
..
textWidthBasis
=
textWidthBasis
..
obscureText
=
obscureText
..
cursorWidth
=
cursorWidth
..
cursorRadius
=
cursorRadius
...
...
packages/flutter/test/material/text_field_test.dart
View file @
2338576a
...
...
@@ -973,7 +973,7 @@ void main() {
final
RenderEditable
renderEditable
=
findRenderEditable
(
tester
);
// There should be no composing.
expect
(
renderEditable
.
isComposingText
,
false
);
expect
(
renderEditable
.
text
,
TextSpan
(
text:
'readonly'
,
style:
renderEditable
.
text
.
style
)
);
});
testWidgets
(
'Dynamically switching between read only and not read only should hide or show collapse cursor'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -3231,6 +3231,30 @@ void main() {
semantics
.
dispose
();
});
testWidgets
(
'Read only TextField identifies as read only text field in semantics'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Material
(
child:
Center
(
child:
TextField
(
maxLength:
10
,
readOnly:
true
,
),
),
),
),
);
expect
(
semantics
,
includesNodeWith
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isTextField
,
SemanticsFlag
.
isReadOnly
])
);
semantics
.
dispose
();
});
void
sendFakeKeyEvent
(
Map
<
String
,
dynamic
>
data
)
{
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
keyEvent
.
name
,
...
...
packages/flutter/test/widgets/selectable_text_test.dart
0 → 100644
View file @
2338576a
This source diff could not be displayed because it is too large. You can
view the blob
instead.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment