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
fb7a5937
Unverified
Commit
fb7a5937
authored
Oct 09, 2018
by
Jonah Williams
Committed by
GitHub
Oct 09, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Basic scroll semantics support (#21764)
parent
59f1f1b6
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
661 additions
and
62 deletions
+661
-62
cupertino_navigation_demo.dart
...gallery/lib/demo/cupertino/cupertino_navigation_demo.dart
+5
-2
pesto_demo.dart
examples/flutter_gallery/lib/demo/pesto_demo.dart
+1
-0
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+43
-0
semantics.dart
packages/flutter/lib/src/semantics/semantics.dart
+98
-3
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+58
-0
scroll_view.dart
packages/flutter/lib/src/widgets/scroll_view.dart
+102
-6
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+44
-3
sliver.dart
packages/flutter/lib/src/widgets/sliver.dart
+185
-0
semantics_test.dart
packages/flutter/test/semantics/semantics_test.dart
+4
-0
automatic_keep_alive_test.dart
packages/flutter/test/widgets/automatic_keep_alive_test.dart
+9
-0
draggable_test.dart
packages/flutter/test/widgets/draggable_test.dart
+1
-0
ensure_visible_test.dart
packages/flutter/test/widgets/ensure_visible_test.dart
+1
-0
keep_alive_test.dart
packages/flutter/test/widgets/keep_alive_test.dart
+4
-0
list_view_viewporting_test.dart
...ages/flutter/test/widgets/list_view_viewporting_test.dart
+1
-0
scrollable_semantics_traversal_order_test.dart
...st/widgets/scrollable_semantics_traversal_order_test.dart
+82
-47
semantics_tester.dart
packages/flutter/test/widgets/semantics_tester.dart
+20
-0
sliver_fill_viewport_test.dart
packages/flutter/test/widgets/sliver_fill_viewport_test.dart
+1
-1
matchers_test.dart
packages/flutter_test/test/matchers_test.dart
+2
-0
No files found.
examples/flutter_gallery/lib/demo/cupertino/cupertino_navigation_demo.dart
View file @
fb7a5937
...
...
@@ -30,6 +30,8 @@ const List<String> coolColorNames = <String>[
'Pervenche'
,
'Sinoper'
,
'Verditer'
,
'Watchet'
,
'Zaffre'
,
];
const
int
_kChildCount
=
50
;
class
CupertinoNavigationDemo
extends
StatelessWidget
{
CupertinoNavigationDemo
()
:
colorItems
=
List
<
Color
>.
generate
(
50
,
(
int
index
)
{
...
...
@@ -146,6 +148,7 @@ class CupertinoDemoTab1 extends StatelessWidget {
Widget
build
(
BuildContext
context
)
{
return
CupertinoPageScaffold
(
child:
CustomScrollView
(
semanticChildCount:
_kChildCount
,
slivers:
<
Widget
>[
CupertinoSliverNavigationBar
(
trailing:
trailingButtons
,
...
...
@@ -163,12 +166,12 @@ class CupertinoDemoTab1 extends StatelessWidget {
(
BuildContext
context
,
int
index
)
{
return
Tab1RowItem
(
index:
index
,
lastItem:
index
==
49
,
lastItem:
index
==
_kChildCount
-
1
,
color:
colorItems
[
index
],
colorName:
colorNameItems
[
index
],
);
},
childCount:
50
,
childCount:
_kChildCount
,
),
),
),
...
...
examples/flutter_gallery/lib/demo/pesto_demo.dart
View file @
fb7a5937
...
...
@@ -91,6 +91,7 @@ class _RecipeGridPageState extends State<RecipeGridPage> {
},
),
body:
CustomScrollView
(
semanticChildCount:
widget
.
recipes
.
length
,
slivers:
<
Widget
>[
_buildAppBar
(
context
,
statusBarHeight
),
_buildBody
(
context
,
statusBarHeight
),
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
fb7a5937
...
...
@@ -4330,6 +4330,49 @@ class RenderExcludeSemantics extends RenderProxyBox {
}
}
/// A render objects that annotates semantics with an index.
///
/// Certain widgets will automatically provide a child index for building
/// semantics. For example, the [ScrollView] uses the index of the first
/// visible child semantics node to determine the
/// [SemanticsConfiguration.scrollIndex].
///
/// See also:
///
/// * [CustomScrollView], for an explanation of scroll semantics.
class
RenderIndexedSemantics
extends
RenderProxyBox
{
/// Creates a render object that annotates the child semantics with an index.
RenderIndexedSemantics
({
RenderBox
child
,
@required
int
index
,
})
:
assert
(
index
!=
null
),
_index
=
index
,
super
(
child
);
/// The index used to annotated child semantics.
int
get
index
=>
_index
;
int
_index
;
set
index
(
int
value
)
{
if
(
value
==
index
)
return
;
_index
=
value
;
markNeedsSemanticsUpdate
();
}
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
config
.
isSemanticBoundary
=
true
;
config
.
indexInParent
=
index
;
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
properties
.
add
(
DiagnosticsProperty
<
int
>(
'index'
,
index
));
}
}
/// Provides an anchor for a [RenderFollowerLayer].
///
/// See also:
...
...
packages/flutter/lib/src/semantics/semantics.dart
View file @
fb7a5937
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/basic.dart
View file @
fb7a5937
...
...
@@ -5553,6 +5553,64 @@ class ExcludeSemantics extends SingleChildRenderObjectWidget {
}
}
/// A widget that annotates the child semantics with an index.
///
/// Semantic indexes are used by TalkBack/Voiceover to make announcements about
/// the current scroll state. Certain widgets like the [ListView] will
/// automatically provide a child index for building semantics. A user may wish
/// to manually provide semanitc indexes if not all child of the scrollable
/// contribute semantics.
///
/// ## Sample code
///
/// The example below handles spacers in a scrollable that don't contribute
/// semantics. The automatic indexes would give the spaces a semantic index,
/// causing scroll announcements to erroneously state that there are four items
/// visible.
///
/// ```dart
/// ListView(
/// addSemanticIndexes: false,
/// semanticChildCount: 2,
/// children: const <Widget>[
/// IndexedSemantics(index: 0, child: Text('First')),
/// Spacer(),
/// IndexedSemantics(index: 1, child: Text('Second')),
/// Spacer(),
/// ],
/// )
/// ```
///
/// See also:
/// * [CustomScrollView], for an explaination of index semantics.
class
IndexedSemantics
extends
SingleChildRenderObjectWidget
{
/// Creates a widget that annotated the first child semantics node with an index.
///
/// [index] must not be null.
const
IndexedSemantics
({
Key
key
,
@required
this
.
index
,
Widget
child
,
})
:
assert
(
index
!=
null
),
super
(
key:
key
,
child:
child
);
/// The index used to annotate the first child semantics node.
final
int
index
;
@override
RenderIndexedSemantics
createRenderObject
(
BuildContext
context
)
=>
RenderIndexedSemantics
(
index:
index
);
@override
void
updateRenderObject
(
BuildContext
context
,
RenderIndexedSemantics
renderObject
)
{
renderObject
.
index
=
index
;
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
properties
.
add
(
DiagnosticsProperty
<
int
>(
'index'
,
index
));
}
}
/// A widget that builds its child.
///
/// Useful for attaching a key to an existing widget.
...
...
packages/flutter/lib/src/widgets/scroll_view.dart
View file @
fb7a5937
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/scrollable.dart
View file @
fb7a5937
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:ui'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
...
...
@@ -79,6 +80,7 @@ class Scrollable extends StatefulWidget {
this
.
physics
,
@required
this
.
viewportBuilder
,
this
.
excludeFromSemantics
=
false
,
this
.
semanticChildCount
,
})
:
assert
(
axisDirection
!=
null
),
assert
(
viewportBuilder
!=
null
),
assert
(
excludeFromSemantics
!=
null
),
...
...
@@ -161,6 +163,23 @@ class Scrollable extends StatefulWidget {
/// exclusion.
final
bool
excludeFromSemantics
;
/// The number of children that will contribute semantic information.
///
/// The value will be null if the number of children is unknown or unbounded.
///
/// Some subtypes of [ScrollView] can infer this value automatically. For
/// example [ListView] will use the number of widgets in the child list,
/// while the [new ListView.separated] constructor will use half that amount.
///
/// For [CustomScrollView] and other types which do not receive a builder
/// or list of widgets, the child count must be explicitly provided.
///
/// See also:
///
/// * [CustomScrollView], for an explanation of scroll semantics.
/// * [SemanticsConfiguration.scrollChildCount], the corresponding semantics property.
final
int
semanticChildCount
;
/// The axis along which the scroll view scrolls.
///
/// Determined by the [axisDirection].
...
...
@@ -509,6 +528,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin
child:
result
,
position:
position
,
allowImplicitScrolling:
widget
?.
physics
?.
allowImplicitScrolling
??
false
,
semanticChildCount:
widget
.
semanticChildCount
,
);
}
...
...
@@ -541,17 +561,20 @@ class _ScrollSemantics extends SingleChildRenderObjectWidget {
Key
key
,
@required
this
.
position
,
@required
this
.
allowImplicitScrolling
,
@required
this
.
semanticChildCount
,
Widget
child
})
:
assert
(
position
!=
null
),
super
(
key:
key
,
child:
child
);
final
ScrollPosition
position
;
final
bool
allowImplicitScrolling
;
final
int
semanticChildCount
;
@override
_RenderScrollSemantics
createRenderObject
(
BuildContext
context
)
{
return
_RenderScrollSemantics
(
position:
position
,
allowImplicitScrolling:
allowImplicitScrolling
,
semanticChildCount:
semanticChildCount
,
);
}
...
...
@@ -559,7 +582,8 @@ class _ScrollSemantics extends SingleChildRenderObjectWidget {
void
updateRenderObject
(
BuildContext
context
,
_RenderScrollSemantics
renderObject
)
{
renderObject
..
allowImplicitScrolling
=
allowImplicitScrolling
..
position
=
position
;
..
position
=
position
..
semanticChildCount
=
semanticChildCount
;
}
}
...
...
@@ -567,9 +591,11 @@ class _RenderScrollSemantics extends RenderProxyBox {
_RenderScrollSemantics
({
@required
ScrollPosition
position
,
@required
bool
allowImplicitScrolling
,
@required
int
semanticChildCount
,
RenderBox
child
,
})
:
_position
=
position
,
_allowImplicitScrolling
=
allowImplicitScrolling
,
_semanticChildCount
=
semanticChildCount
,
assert
(
position
!=
null
),
super
(
child
)
{
position
.
addListener
(
markNeedsSemanticsUpdate
);
}
...
...
@@ -597,6 +623,15 @@ class _RenderScrollSemantics extends RenderProxyBox {
markNeedsSemanticsUpdate
();
}
int
get
semanticChildCount
=>
_semanticChildCount
;
int
_semanticChildCount
;
set
semanticChildCount
(
int
value
)
{
if
(
value
==
semanticChildCount
)
return
;
_semanticChildCount
=
value
;
markNeedsSemanticsUpdate
();
}
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
...
...
@@ -606,7 +641,8 @@ class _RenderScrollSemantics extends RenderProxyBox {
..
hasImplicitScrolling
=
allowImplicitScrolling
..
scrollPosition
=
_position
.
pixels
..
scrollExtentMax
=
_position
.
maxScrollExtent
..
scrollExtentMin
=
_position
.
minScrollExtent
;
..
scrollExtentMin
=
_position
.
minScrollExtent
..
scrollChildCount
=
semanticChildCount
;
}
}
...
...
@@ -624,15 +660,20 @@ class _RenderScrollSemantics extends RenderProxyBox {
..
isMergedIntoParent
=
node
.
isPartOfNodeMerging
..
rect
=
Offset
.
zero
&
node
.
rect
.
size
;
int
firstVisibleIndex
;
final
List
<
SemanticsNode
>
excluded
=
<
SemanticsNode
>[
_innerNode
];
final
List
<
SemanticsNode
>
included
=
<
SemanticsNode
>[];
for
(
SemanticsNode
child
in
children
)
{
assert
(
child
.
isTagged
(
RenderViewport
.
useTwoPaneSemantics
));
if
(
child
.
isTagged
(
RenderViewport
.
excludeFromScrolling
))
excluded
.
add
(
child
);
else
else
{
if
(!
child
.
hasFlag
(
SemanticsFlag
.
isHidden
))
firstVisibleIndex
??=
child
.
indexInParent
;
included
.
add
(
child
);
}
}
config
.
scrollIndex
=
firstVisibleIndex
;
node
.
updateWith
(
config:
null
,
childrenInInversePaintOrder:
excluded
);
_innerNode
.
updateWith
(
config:
config
,
childrenInInversePaintOrder:
included
);
}
...
...
packages/flutter/lib/src/widgets/sliver.dart
View file @
fb7a5937
...
...
@@ -16,6 +16,25 @@ export 'package:flutter/rendering.dart' show
SliverGridDelegateWithFixedCrossAxisCount
,
SliverGridDelegateWithMaxCrossAxisExtent
;
// Examples can assume:
// SliverGridDelegateWithMaxCrossAxisExtent _gridDelegate;
/// A callback which produces a semantic index given a widget and the local index.
///
/// Return a null value to prevent a widget from receiving an index.
///
/// A semantic index is used to tag child semantic nodes for accessibility
/// announcements in scroll view.
///
/// See also:
///
/// * [CustomScrollView], for an explanation of scroll semantics.
/// * [SliverChildBuilderDelegate], for an explanation of how this is used to
/// generate indexes.
typedef
SemanticIndexCallback
=
int
Function
(
Widget
widget
,
int
localIndex
);
int
_kDefaultSemanticIndexCallback
(
Widget
_
,
int
localIndex
)
=>
localIndex
;
/// A delegate that supplies children for slivers.
///
/// Many slivers lazily construct their box children to avoid creating more
...
...
@@ -188,10 +207,96 @@ abstract class SliverChildDelegate {
/// default) and in [RepaintBoundary] widgets if [addRepaintBoundaries] is true
/// (also the default).
///
/// ## Accessibility
///
/// The [CustomScrollView] requires that its semantic children are annotated
/// using [IndexedSemantics]. This is done by default in the delegate with
/// the `addSemanticIndexes` parameter set to true.
///
/// If multiple delegates are used in a single scroll view, then the indexes
/// will not be correct by default. The `semanticIndexOffset` can be used to
/// offset the semantic indexes of each delegate so that the indexes are
/// monotonically increasing. For example, if a scroll view contains two
/// delegates where the first has 10 children contributing semantics, then the
/// second delegate should offset its children by 10.
///
/// ## Sample code
///
/// This sample code shows how to use `semanticIndexOffset` to handle multiple
/// delegates in a single scroll view.
///
/// ```dart
/// CustomScrollView(
/// semanticChildCount: 4,
/// slivers: <Widget>[
/// SliverGrid(
/// gridDelegate: _gridDelegate,
/// delegate: SliverChildBuilderDelegate(
/// (BuildContext context, int index) {
/// return Text('...');
/// },
/// childCount: 2,
/// ),
/// ),
/// SliverGrid(
/// gridDelegate: _gridDelegate,
/// delegate: SliverChildBuilderDelegate(
/// (BuildContext context, int index) {
/// return Text('...');
/// },
/// childCount: 2,
/// semanticIndexOffset: 2,
/// ),
/// ),
/// ],
/// )
/// ```
///
/// In certain cases, only a subset of child widgets should be annotated
/// with a semantic index. For example, in [new ListView.separated()] the
/// separators do not have an index assocaited with them. This is done by
/// providing a `semanticIndexCallback` which returns null for separators
/// indexes and rounds the non-separator indexes down by half.
///
/// ## Sample code
///
/// This sample code shows how to use `semanticIndexCallback` to handle
/// annotating a subset of child nodes with a semantic index. There is
/// a [Spacer] widget at odd indexes which should not have a semantic
/// index.
///
/// ```dart
/// CustomScrollView(
/// semanticChildCount: 5,
/// slivers: <Widget>[
/// SliverGrid(
/// gridDelegate: _gridDelegate,
/// delegate: SliverChildBuilderDelegate(
/// (BuildContext context, int index) {
/// if (index.isEven) {
/// return Text('...');
/// }
/// return Spacer();
/// },
/// semanticIndexCallback: (Widget widget, int localIndex) {
/// if (localIndex.isEven) {
/// return localIndex ~/ 2;
/// }
/// return null;
/// },
/// childCount: 10,
/// ),
/// ),
/// ],
/// )
/// ```
///
/// See also:
///
/// * [SliverChildListDelegate], which is a delegate that has an explicit list
/// of children.
/// * [IndexedSemantics], for an example of manually annotating child nodes
/// with semantic indexes.
class
SliverChildBuilderDelegate
extends
SliverChildDelegate
{
/// Creates a delegate that supplies children for slivers using the given
/// builder callback.
...
...
@@ -203,6 +308,9 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
this
.
childCount
,
this
.
addAutomaticKeepAlives
=
true
,
this
.
addRepaintBoundaries
=
true
,
this
.
addSemanticIndexes
=
true
,
this
.
semanticIndexCallback
=
_kDefaultSemanticIndexCallback
,
this
.
semanticIndexOffset
=
0
,
})
:
assert
(
builder
!=
null
),
assert
(
addAutomaticKeepAlives
!=
null
),
assert
(
addRepaintBoundaries
!=
null
);
...
...
@@ -250,6 +358,27 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
/// Defaults to true.
final
bool
addRepaintBoundaries
;
/// Whether to wrap each child in an [IndexedSemantics].
///
/// Typically, children in a scrolling container must be annotated with a
/// semantic index in order to generate the correct accessibility
/// announcements. This should only be set to false if the indexes have
/// already been provided by wrapping the correct child widgets in an
/// indexed child semantics widget.
///
/// Defaults to true.
final
bool
addSemanticIndexes
;
/// An initial offset to add to the semantic indexes generated by this widget.
///
/// Defaults to zero.
final
int
semanticIndexOffset
;
/// A [SemanticIndexCallback] which is used when [addSemanticIndexes] is true.
///
/// Defaults to providing an index for each widget.
final
SemanticIndexCallback
semanticIndexCallback
;
@override
Widget
build
(
BuildContext
context
,
int
index
)
{
assert
(
builder
!=
null
);
...
...
@@ -260,6 +389,11 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
return
null
;
if
(
addRepaintBoundaries
)
child
=
RepaintBoundary
.
wrap
(
child
,
index
);
if
(
addSemanticIndexes
)
{
final
int
semanticIndex
=
semanticIndexCallback
(
child
,
index
);
if
(
semanticIndex
!=
null
)
child
=
IndexedSemantics
(
index:
semanticIndex
+
semanticIndexOffset
,
child:
child
);
}
if
(
addAutomaticKeepAlives
)
child
=
AutomaticKeepAlive
(
child:
child
);
return
child
;
...
...
@@ -297,6 +431,28 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
/// default) and in [RepaintBoundary] widgets if [addRepaintBoundaries] is true
/// (also the default).
///
/// ## Accessibility
///
/// The [CustomScrollView] requires that its semantic children are annotated
/// using [IndexedSemantics]. This is done by default in the delegate with
/// the `addSemanticIndexes` parameter set to true.
///
/// If multiple delegates are used in a single scroll view, then the indexes
/// will not be correct by default. The `semanticIndexOffset` can be used to
/// offset the semantic indexes of each delegate so that the indexes are
/// monotonically increasing. For example, if a scroll view contains two
/// delegates where the first has 10 children contributing semantics, then the
/// second delegate should offset its children by 10.
///
/// In certain cases, only a subset of child widgets should be annotated
/// with a semantic index. For example, in [new ListView.separated()] the
/// separators do not have an index assocaited with them. This is done by
/// providing a `semanticIndexCallback` which returns null for separators
/// indexes and rounds the non-separator indexes down by half.
///
/// See [SliverChildBuilderDelegate] for sample code using
/// `semanticIndexOffset` and `semanticIndexCallback`.
///
/// See also:
///
/// * [SliverChildBuilderDelegate], which is a delegate that uses a builder
...
...
@@ -311,6 +467,9 @@ class SliverChildListDelegate extends SliverChildDelegate {
this
.
children
,
{
this
.
addAutomaticKeepAlives
=
true
,
this
.
addRepaintBoundaries
=
true
,
this
.
addSemanticIndexes
=
true
,
this
.
semanticIndexCallback
=
_kDefaultSemanticIndexCallback
,
this
.
semanticIndexOffset
=
0
,
})
:
assert
(
children
!=
null
),
assert
(
addAutomaticKeepAlives
!=
null
),
assert
(
addRepaintBoundaries
!=
null
);
...
...
@@ -340,6 +499,27 @@ class SliverChildListDelegate extends SliverChildDelegate {
/// Defaults to true.
final
bool
addRepaintBoundaries
;
/// Whether to wrap each child in an [IndexedSemantics].
///
/// Typically, children in a scrolling container must be annotated with a
/// semantic index in order to generate the correct accessibility
/// announcements. This should only be set to false if the indexes have
/// already been provided by wrapping the correct child widgets in an
/// indexed child semantics widget.
///
/// Defaults to true.
final
bool
addSemanticIndexes
;
/// An initial offset to add to the semantic indexes generated by this widget.
///
/// Defaults to zero.
final
int
semanticIndexOffset
;
/// A [SemanticIndexCallback] which is used when [addSemanticIndexes] is true.
///
/// Defaults to providing an index for each widget.
final
SemanticIndexCallback
semanticIndexCallback
;
/// The widgets to display.
final
List
<
Widget
>
children
;
...
...
@@ -352,6 +532,11 @@ class SliverChildListDelegate extends SliverChildDelegate {
assert
(
child
!=
null
);
if
(
addRepaintBoundaries
)
child
=
RepaintBoundary
.
wrap
(
child
,
index
);
if
(
addSemanticIndexes
)
{
final
int
semanticIndex
=
semanticIndexCallback
(
child
,
index
);
if
(
semanticIndex
!=
null
)
child
=
IndexedSemantics
(
index:
semanticIndex
+
semanticIndexOffset
,
child:
child
);
}
if
(
addAutomaticKeepAlives
)
child
=
AutomaticKeepAlive
(
child:
child
);
return
child
;
...
...
packages/flutter/test/semantics/semantics_test.dart
View file @
fb7a5937
...
...
@@ -348,6 +348,8 @@ void main() {
' hint: ""
\n
'
' textDirection: null
\n
'
' sortKey: null
\n
'
' scrollChildren: null
\n
'
' scrollIndex: null
\n
'
' scrollExtentMin: null
\n
'
' scrollPosition: null
\n
'
' scrollExtentMax: null
\n
'
...
...
@@ -438,6 +440,8 @@ void main() {
' hint: ""
\n
'
' textDirection: null
\n
'
' sortKey: null
\n
'
' scrollChildren: null
\n
'
' scrollIndex: null
\n
'
' scrollExtentMin: null
\n
'
' scrollPosition: null
\n
'
' scrollExtentMax: null
\n
'
...
...
packages/flutter/test/widgets/automatic_keep_alive_test.dart
View file @
fb7a5937
...
...
@@ -70,6 +70,7 @@ void tests({ @required bool impliedMode }) {
child:
ListView
(
addAutomaticKeepAlives:
impliedMode
,
addRepaintBoundaries:
impliedMode
,
addSemanticIndexes:
false
,
itemExtent:
12.3
,
// about 50 widgets visible
cacheExtent:
0.0
,
children:
generateList
(
const
Placeholder
(),
impliedMode:
impliedMode
),
...
...
@@ -117,6 +118,7 @@ void tests({ @required bool impliedMode }) {
child:
ListView
(
addAutomaticKeepAlives:
impliedMode
,
addRepaintBoundaries:
impliedMode
,
addSemanticIndexes:
false
,
cacheExtent:
0.0
,
children:
generateList
(
Container
(
height:
12.3
,
child:
const
Placeholder
()),
// about 50 widgets visible
...
...
@@ -166,6 +168,7 @@ void tests({ @required bool impliedMode }) {
child:
GridView
.
count
(
addAutomaticKeepAlives:
impliedMode
,
addRepaintBoundaries:
impliedMode
,
addSemanticIndexes:
false
,
crossAxisCount:
2
,
childAspectRatio:
400.0
/
24.6
,
// about 50 widgets visible
cacheExtent:
0.0
,
...
...
@@ -222,6 +225,7 @@ void main() {
child:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
cacheExtent:
0.0
,
children:
<
Widget
>[
AutomaticKeepAlive
(
...
...
@@ -305,6 +309,7 @@ void main() {
child:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
cacheExtent:
0.0
,
children:
<
Widget
>[
AutomaticKeepAlive
(
...
...
@@ -360,6 +365,7 @@ void main() {
child:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
cacheExtent:
0.0
,
children:
<
Widget
>[
AutomaticKeepAlive
(
...
...
@@ -423,6 +429,7 @@ void main() {
child:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
cacheExtent:
0.0
,
children:
<
Widget
>[
AutomaticKeepAlive
(
...
...
@@ -468,6 +475,7 @@ void main() {
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ListView
.
builder
(
addSemanticIndexes:
false
,
itemCount:
50
,
itemBuilder:
(
BuildContext
context
,
int
index
){
if
(
index
==
0
){
...
...
@@ -501,6 +509,7 @@ void main() {
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ListView
.
builder
(
addSemanticIndexes:
false
,
itemCount:
250
,
itemBuilder:
(
BuildContext
context
,
int
index
){
if
(
index
%
2
==
0
){
...
...
packages/flutter/test/widgets/draggable_test.dart
View file @
fb7a5937
...
...
@@ -1658,6 +1658,7 @@ void main() {
await
tester
.
pumpWidget
(
MaterialApp
(
home:
ListView
(
scrollDirection:
Axis
.
horizontal
,
addSemanticIndexes:
false
,
children:
<
Widget
>[
DragTarget
<
int
>(
builder:
(
BuildContext
context
,
List
<
int
>
data
,
List
<
dynamic
>
rejects
)
{
...
...
packages/flutter/test/widgets/ensure_visible_test.dart
View file @
fb7a5937
...
...
@@ -48,6 +48,7 @@ Widget buildListView(Axis scrollDirection, { bool reverse = false, bool shrinkWr
child:
ListView
(
scrollDirection:
scrollDirection
,
reverse:
reverse
,
addSemanticIndexes:
false
,
shrinkWrap:
shrinkWrap
,
children:
<
Widget
>[
Container
(
key:
const
ValueKey
<
int
>(
0
),
width:
200.0
,
height:
200.0
),
...
...
packages/flutter/test/widgets/keep_alive_test.dart
View file @
fb7a5937
...
...
@@ -50,6 +50,7 @@ void main() {
cacheExtent:
0.0
,
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
itemExtent:
12.3
,
// about 50 widgets visible
children:
generateList
(
const
Placeholder
()),
),
...
...
@@ -97,6 +98,7 @@ void main() {
cacheExtent:
0.0
,
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
children:
generateList
(
Container
(
height:
12.3
,
child:
const
Placeholder
())),
// about 50 widgets visible
),
),
...
...
@@ -143,6 +145,7 @@ void main() {
cacheExtent:
0.0
,
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
crossAxisCount:
2
,
childAspectRatio:
400.0
/
24.6
,
// about 50 widgets visible
children:
generateList
(
Container
(
child:
const
Placeholder
())),
...
...
@@ -190,6 +193,7 @@ void main() {
child:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
itemExtent:
400.0
,
// 2 visible children
children:
generateList
(
const
Placeholder
()),
),
...
...
packages/flutter/test/widgets/list_view_viewporting_test.dart
View file @
fb7a5937
...
...
@@ -308,6 +308,7 @@ void main() {
textDirection:
TextDirection
.
ltr
,
child:
ListView
(
addAutomaticKeepAlives:
false
,
addSemanticIndexes:
false
,
children:
<
Widget
>[
Container
(
height:
100.0
),
Container
(
height:
100.0
),
...
...
packages/flutter/test/widgets/scrollable_semantics_traversal_order_test.dart
View file @
fb7a5937
...
...
@@ -42,6 +42,7 @@ void main() {
data:
const
MediaQueryData
(),
child:
CustomScrollView
(
controller:
ScrollController
(
initialScrollOffset:
3000.0
),
semanticChildCount:
30
,
slivers:
<
Widget
>[
SliverList
(
delegate:
SliverChildListDelegate
(
listChildren
),
...
...
@@ -62,6 +63,8 @@ void main() {
TestSemantics
(
children:
<
TestSemantics
>[
TestSemantics
(
scrollIndex:
15
,
scrollChildren:
30
,
actions:
<
SemanticsAction
>[
SemanticsAction
.
scrollUp
,
SemanticsAction
.
scrollDown
,
...
...
@@ -69,67 +72,99 @@ void main() {
children:
<
TestSemantics
>[
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'Item 13a'
,
textDirection:
TextDirection
.
ltr
,
)
,
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]
,
label:
'item 13b'
,
textDirection:
TextDirection
.
ltr
,
)
,
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]
,
label:
'Item 14a'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]
,
label:
'Item 13a'
,
textDirection:
TextDirection
.
ltr
,
)
,
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]
,
label:
'item 13b'
,
textDirection:
TextDirection
.
ltr
,
)
,
]
,
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'item 14b'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'Item 15a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'item 15b'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'Item 16a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'item 16b'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'Item 17a'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'Item 14a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'item 14b'
,
textDirection:
TextDirection
.
ltr
,
),
]
),
TestSemantics
(
label:
'item 17b'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
label:
'Item 15a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'item 15b'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'Item 18a'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
label:
'Item 16a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'item 16b'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'item 18b'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
label:
'Item 17a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'item 17b'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'Item 19a'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'Item 18a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'item 18b'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'item 19b'
,
textDirection:
TextDirection
.
ltr
,
children:
<
TestSemantics
>[
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'Item 19a'
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
],
label:
'item 19b'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
],
),
...
...
@@ -181,7 +216,7 @@ void main() {
slivers:
<
Widget
>[
SliverFixedExtentList
(
itemExtent:
200.0
,
delegate:
SliverChildListDelegate
(
listChildren
),
delegate:
SliverChildListDelegate
(
listChildren
,
addSemanticIndexes:
false
),
),
],
),
...
...
packages/flutter/test/widgets/semantics_tester.dart
View file @
fb7a5937
...
...
@@ -48,6 +48,8 @@ class TestSemantics {
this
.
transform
,
this
.
textSelection
,
this
.
children
=
const
<
TestSemantics
>[],
this
.
scrollIndex
,
this
.
scrollChildren
,
Iterable
<
SemanticsTag
>
tags
,
})
:
assert
(
flags
is
int
||
flags
is
List
<
SemanticsFlag
>),
assert
(
actions
is
int
||
actions
is
List
<
SemanticsAction
>),
...
...
@@ -73,6 +75,8 @@ class TestSemantics {
this
.
transform
,
this
.
textSelection
,
this
.
children
=
const
<
TestSemantics
>[],
this
.
scrollIndex
,
this
.
scrollChildren
,
Iterable
<
SemanticsTag
>
tags
,
})
:
id
=
0
,
assert
(
flags
is
int
||
flags
is
List
<
SemanticsFlag
>),
...
...
@@ -109,6 +113,8 @@ class TestSemantics {
Matrix4
transform
,
this
.
textSelection
,
this
.
children
=
const
<
TestSemantics
>[],
this
.
scrollIndex
,
this
.
scrollChildren
,
Iterable
<
SemanticsTag
>
tags
,
})
:
assert
(
flags
is
int
||
flags
is
List
<
SemanticsFlag
>),
assert
(
actions
is
int
||
actions
is
List
<
SemanticsAction
>),
...
...
@@ -200,6 +206,12 @@ class TestSemantics {
/// parent).
final
Matrix4
transform
;
/// The index of the first visible semantic node within a scrollable.
final
int
scrollIndex
;
/// The total number of semantic nodes within a scrollable.
final
int
scrollChildren
;
final
TextSelection
textSelection
;
static
Matrix4
_applyRootChildScale
(
Matrix4
transform
)
{
...
...
@@ -270,6 +282,12 @@ class TestSemantics {
if
(
textSelection
?.
baseOffset
!=
nodeData
.
textSelection
?.
baseOffset
||
textSelection
?.
extentOffset
!=
nodeData
.
textSelection
?.
extentOffset
)
{
return
fail
(
'expected node id
$id
to have textSelection [
${textSelection?.baseOffset}
,
${textSelection?.end}
] but found: [
${nodeData.textSelection?.baseOffset}
,
${nodeData.textSelection?.extentOffset}
].'
);
}
if
(
scrollIndex
!=
null
&&
scrollIndex
!=
nodeData
.
scrollIndex
)
{
return
fail
(
'expected node id
$id
to have scrollIndex
$scrollIndex
but found scrollIndex
${nodeData.scrollIndex}
.'
);
}
if
(
scrollChildren
!=
null
&&
scrollChildren
!=
nodeData
.
scrollChildCount
)
{
return
fail
(
'expected node id
$id
to have scrollIndex
$scrollChildren
but found scrollIndex
${nodeData.scrollChildCount}
.'
);
}
final
int
childrenCount
=
node
.
mergeAllDescendantsIntoThisNode
?
0
:
node
.
childrenCount
;
if
(
children
.
length
!=
childrenCount
)
return
fail
(
'expected node id
$id
to have
${children.length}
child
${ children.length == 1 ? "" : "ren" }
but found
$childrenCount
.'
);
...
...
@@ -322,6 +340,8 @@ class TestSemantics {
buf
.
writeln
(
'
$indent
textDirection:
$textDirection
,'
);
if
(
textSelection
?.
isValid
==
true
)
buf
.
writeln
(
'
$indent
textSelection:
\n
[
${textSelection.start}
,
${textSelection.end}
],'
);
if
(
scrollIndex
!=
null
)
buf
.
writeln
(
'
$indent
scrollIndex:
$scrollIndex
,'
);
if
(
rect
!=
null
)
buf
.
writeln
(
'
$indent
rect:
$rect
,'
);
if
(
transform
!=
null
)
...
...
packages/flutter/test/widgets/sliver_fill_viewport_test.dart
View file @
fb7a5937
...
...
@@ -17,7 +17,7 @@ void main() {
child:
CustomScrollView
(
slivers:
<
Widget
>[
SliverFillViewport
(
delegate:
SliverChildListDelegate
(
children
,
addAutomaticKeepAlives:
false
),
delegate:
SliverChildListDelegate
(
children
,
addAutomaticKeepAlives:
false
,
addSemanticIndexes:
false
),
),
],
),
...
...
packages/flutter_test/test/matchers_test.dart
View file @
fb7a5937
...
...
@@ -495,6 +495,8 @@ void main() {
textDirection:
TextDirection
.
ltr
,
rect:
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
textSelection:
null
,
scrollIndex:
null
,
scrollChildCount:
null
,
scrollPosition:
null
,
scrollExtentMax:
null
,
scrollExtentMin:
null
,
...
...
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