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
a30b109c
Commit
a30b109c
authored
Oct 05, 2017
by
Adam Barth
Committed by
GitHub
Oct 05, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add RTL support to ListBody (#12414)
Fixes #11930
parent
cd3715a8
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
388 additions
and
199 deletions
+388
-199
rendering.dart
packages/flutter/lib/rendering.dart
+1
-1
mergeable_material.dart
packages/flutter/lib/src/material/mergeable_material.dart
+9
-5
basic_types.dart
packages/flutter/lib/src/painting/basic_types.dart
+107
-0
list_body.dart
packages/flutter/lib/src/rendering/list_body.dart
+78
-61
sliver.dart
packages/flutter/lib/src/rendering/sliver.dart
+0
-105
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+59
-2
scroll_view.dart
packages/flutter/lib/src/widgets/scroll_view.dart
+1
-11
single_child_scroll_view.dart
...ges/flutter/lib/src/widgets/single_child_scroll_view.dart
+2
-12
paragraph_intrinsics_test.dart
...ges/flutter/test/rendering/paragraph_intrinsics_test.dart
+2
-2
list_body_test.dart
packages/flutter/test/widgets/list_body_test.dart
+109
-0
finders.dart
packages/flutter_test/lib/src/finders.dart
+20
-0
No files found.
packages/flutter/lib/rendering.dart
View file @
a30b109c
...
...
@@ -32,7 +32,6 @@ export 'package:vector_math/vector_math_64.dart' show Matrix4;
export
'src/rendering/animated_size.dart'
;
export
'src/rendering/binding.dart'
;
export
'src/rendering/block.dart'
;
export
'src/rendering/box.dart'
;
export
'src/rendering/custom_layout.dart'
;
export
'src/rendering/debug.dart'
;
...
...
@@ -42,6 +41,7 @@ export 'src/rendering/flex.dart';
export
'src/rendering/flow.dart'
;
export
'src/rendering/image.dart'
;
export
'src/rendering/layer.dart'
;
export
'src/rendering/list_body.dart'
;
export
'src/rendering/node.dart'
;
export
'src/rendering/object.dart'
;
export
'src/rendering/paragraph.dart'
;
...
...
packages/flutter/lib/src/material/mergeable_material.dart
View file @
a30b109c
...
...
@@ -649,11 +649,15 @@ class _MergeableMaterialListBody extends ListBody {
final
List
<
MergeableMaterialItem
>
items
;
final
List
<
BoxShadow
>
boxShadows
;
AxisDirection
_getDirection
(
BuildContext
context
)
{
return
getAxisDirectionFromAxisReverseAndDirectionality
(
context
,
mainAxis
,
false
);
}
@override
RenderListBody
createRenderObject
(
BuildContext
context
)
{
return
new
_RenderMergeableMaterialListBody
(
mainAxis:
mainAxis
,
boxShadows:
boxShadows
axisDirection:
_getDirection
(
context
)
,
boxShadows:
boxShadows
,
);
}
...
...
@@ -661,7 +665,7 @@ class _MergeableMaterialListBody extends ListBody {
void
updateRenderObject
(
BuildContext
context
,
RenderListBody
renderObject
)
{
final
_RenderMergeableMaterialListBody
materialRenderListBody
=
renderObject
;
materialRenderListBody
..
mainAxis
=
mainAxis
..
axisDirection
=
_getDirection
(
context
)
..
boxShadows
=
boxShadows
;
}
}
...
...
@@ -669,9 +673,9 @@ class _MergeableMaterialListBody extends ListBody {
class
_RenderMergeableMaterialListBody
extends
RenderListBody
{
_RenderMergeableMaterialListBody
({
List
<
RenderBox
>
children
,
Axis
mainAxis:
Axis
.
vertical
,
Axis
Direction
axisDirection:
AxisDirection
.
down
,
this
.
boxShadows
})
:
super
(
children:
children
,
mainAxis:
mainAxis
);
})
:
super
(
children:
children
,
axisDirection:
axisDirection
);
List
<
BoxShadow
>
boxShadows
;
...
...
packages/flutter/lib/src/painting/basic_types.dart
View file @
a30b109c
...
...
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
show
TextDirection
;
export
'dart:ui'
show
BlendMode
,
BlurStyle
,
...
...
@@ -157,3 +159,108 @@ enum VerticalDirection {
/// The "start" is at the top, the "end" is at the bottom.
down
,
}
/// A direction along either the horizontal or vertical [Axis].
enum
AxisDirection
{
/// Zero is at the bottom and positive values are above it: ⇈
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A at
/// the bottom and the Z at the top. This is an unusual configuration.
up
,
/// Zero is on the left and positive values are to the right of it: ⇉
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A on
/// the left and the Z on the right. This is the ordinary reading order for a
/// horizontal set of tabs in an English application, for example.
right
,
/// Zero is at the top and positive values are below it: ⇊
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A at
/// the top and the Z at the bottom. This is the ordinary reading order for a
/// vertical list.
down
,
/// Zero is to the right and positive values are to the left of it: ⇇
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A at
/// the right and the Z at the left. This is the ordinary reading order for a
/// horizontal set of tabs in a Hebrew application, for example.
left
,
}
/// Returns the [Axis] that contains the given [AxisDirection].
///
/// Specifically, returns [Axis.vertical] for [AxisDirection.up] and
/// [AxisDirection.down] and returns [Axis.horizontal] for [AxisDirection.left]
/// and [AxisDirection.right].
Axis
axisDirectionToAxis
(
AxisDirection
axisDirection
)
{
assert
(
axisDirection
!=
null
);
switch
(
axisDirection
)
{
case
AxisDirection
.
up
:
case
AxisDirection
.
down
:
return
Axis
.
vertical
;
case
AxisDirection
.
left
:
case
AxisDirection
.
right
:
return
Axis
.
horizontal
;
}
return
null
;
}
/// Returns the [AxisDirection] in which reading occurs in the given [TextDirection].
///
/// Specifically, returns [AxisDirection.left] for [TextDirection.rtl] and
/// [AxisDirection.right] for [TextDirection.ltr].
AxisDirection
textDirectionToAxisDirection
(
TextDirection
textDirection
)
{
assert
(
textDirection
!=
null
);
switch
(
textDirection
)
{
case
TextDirection
.
rtl
:
return
AxisDirection
.
left
;
case
TextDirection
.
ltr
:
return
AxisDirection
.
right
;
}
return
null
;
}
/// Returns the opposite of the given [AxisDirection].
///
/// Specifically, returns [AxisDirection.up] for [AxisDirection.down] (and
/// vice versa), as well as [AxisDirection.left] for [AxisDirection.right] (and
/// vice versa).
///
/// See also:
///
/// * [flipAxis], which does the same thing for [Axis] values.
AxisDirection
flipAxisDirection
(
AxisDirection
axisDirection
)
{
assert
(
axisDirection
!=
null
);
switch
(
axisDirection
)
{
case
AxisDirection
.
up
:
return
AxisDirection
.
down
;
case
AxisDirection
.
right
:
return
AxisDirection
.
left
;
case
AxisDirection
.
down
:
return
AxisDirection
.
up
;
case
AxisDirection
.
left
:
return
AxisDirection
.
right
;
}
return
null
;
}
/// Returns whether travelling along the given axis direction visits coordinates
/// along that axis in numerically decreasing order.
///
/// Specifically, returns true for [AxisDirection.up] and [AxisDirection.left]
/// and false for [AxisDirection.down] for [AxisDirection.right].
bool
axisDirectionIsReversed
(
AxisDirection
axisDirection
)
{
assert
(
axisDirection
!=
null
);
switch
(
axisDirection
)
{
case
AxisDirection
.
up
:
case
AxisDirection
.
left
:
return
true
;
case
AxisDirection
.
down
:
case
AxisDirection
.
right
:
return
false
;
}
return
null
;
}
packages/flutter/lib/src/rendering/
block
.dart
→
packages/flutter/lib/src/rendering/
list_body
.dart
View file @
a30b109c
...
...
@@ -31,8 +31,9 @@ class RenderListBody extends RenderBox
/// By default, children are arranged along the vertical axis.
RenderListBody
({
List
<
RenderBox
>
children
,
Axis
mainAxis:
Axis
.
vertical
,
})
:
_mainAxis
=
mainAxis
{
AxisDirection
axisDirection:
AxisDirection
.
down
,
})
:
assert
(
axisDirection
!=
null
),
_axisDirection
=
axisDirection
{
addAll
(
children
);
}
...
...
@@ -42,41 +43,17 @@ class RenderListBody extends RenderBox
child
.
parentData
=
new
ListBodyParentData
();
}
/// The direction to use as the main axis.
Axis
get
mainAxis
=>
_mainAxis
;
Axis
_mainAxis
;
set
mainAxis
(
Axis
value
)
{
if
(
_mainAxis
!=
value
)
{
_mainAxis
=
value
;
markNeedsLayout
();
}
}
BoxConstraints
_getInnerConstraints
(
BoxConstraints
constraints
)
{
assert
(
_mainAxis
!=
null
);
switch
(
_mainAxis
)
{
case
Axis
.
horizontal
:
return
new
BoxConstraints
.
tightFor
(
height:
constraints
.
maxHeight
);
case
Axis
.
vertical
:
return
new
BoxConstraints
.
tightFor
(
width:
constraints
.
maxWidth
);
}
return
null
;
AxisDirection
get
axisDirection
=>
_axisDirection
;
AxisDirection
_axisDirection
;
set
axisDirection
(
AxisDirection
value
)
{
assert
(
value
!=
null
);
if
(
_axisDirection
==
value
)
return
;
_axisDirection
=
value
;
markNeedsLayout
();
}
double
get
_mainAxisExtent
{
final
RenderBox
child
=
lastChild
;
if
(
child
==
null
)
return
0.0
;
final
BoxParentData
parentData
=
child
.
parentData
;
assert
(
mainAxis
!=
null
);
switch
(
mainAxis
)
{
case
Axis
.
horizontal
:
return
parentData
.
offset
.
dx
+
child
.
size
.
width
;
case
Axis
.
vertical
:
return
parentData
.
offset
.
dy
+
child
.
size
.
height
;
}
return
null
;
}
Axis
get
mainAxis
=>
axisDirectionToAxis
(
axisDirection
);
@override
void
performLayout
()
{
...
...
@@ -124,41 +101,81 @@ class RenderListBody extends RenderBox
'This is relatively expensive, however.'
// (that's why we don't do it automatically)
);
}());
final
BoxConstraints
innerConstraints
=
_getInnerConstraints
(
constraints
);
double
position
=
0.0
;
double
mainAxisExtent
=
0.0
;
RenderBox
child
=
firstChild
;
while
(
child
!=
null
)
{
child
.
layout
(
innerConstraints
,
parentUsesSize:
true
);
final
ListBodyParentData
childParentData
=
child
.
parentData
;
switch
(
mainAxis
)
{
case
Axis
.
horizontal
:
childParentData
.
offset
=
new
Offset
(
position
,
0.0
);
position
+=
child
.
size
.
width
;
break
;
case
Axis
.
vertical
:
childParentData
.
offset
=
new
Offset
(
0.0
,
position
);
position
+=
child
.
size
.
height
;
break
;
switch
(
axisDirection
)
{
case
AxisDirection
.
right
:
final
BoxConstraints
innerConstraints
=
new
BoxConstraints
.
tightFor
(
height:
constraints
.
maxHeight
);
while
(
child
!=
null
)
{
child
.
layout
(
innerConstraints
,
parentUsesSize:
true
);
final
ListBodyParentData
childParentData
=
child
.
parentData
;
childParentData
.
offset
=
new
Offset
(
mainAxisExtent
,
0.0
);
mainAxisExtent
+=
child
.
size
.
width
;
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
switch
(
mainAxis
)
{
case
Axis
.
horizontal
:
size
=
constraints
.
constrain
(
new
Size
(
_mainAxisExtent
,
constraints
.
maxHeight
));
break
;
case
Axis
.
vertical
:
size
=
constraints
.
constrain
(
new
Size
(
constraints
.
maxWidth
,
_mainAxisExtent
));
break
;
size
=
constraints
.
constrain
(
new
Size
(
mainAxisExtent
,
constraints
.
maxHeight
));
break
;
case
AxisDirection
.
left
:
final
BoxConstraints
innerConstraints
=
new
BoxConstraints
.
tightFor
(
height:
constraints
.
maxHeight
);
while
(
child
!=
null
)
{
child
.
layout
(
innerConstraints
,
parentUsesSize:
true
);
final
ListBodyParentData
childParentData
=
child
.
parentData
;
mainAxisExtent
+=
child
.
size
.
width
;
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
double
position
=
0.0
;
child
=
firstChild
;
while
(
child
!=
null
)
{
final
ListBodyParentData
childParentData
=
child
.
parentData
;
position
+=
child
.
size
.
width
;
childParentData
.
offset
=
new
Offset
(
mainAxisExtent
-
position
,
0.0
);
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
size
=
constraints
.
constrain
(
new
Size
(
mainAxisExtent
,
constraints
.
maxHeight
));
break
;
case
AxisDirection
.
down
:
final
BoxConstraints
innerConstraints
=
new
BoxConstraints
.
tightFor
(
width:
constraints
.
maxWidth
);
while
(
child
!=
null
)
{
child
.
layout
(
innerConstraints
,
parentUsesSize:
true
);
final
ListBodyParentData
childParentData
=
child
.
parentData
;
childParentData
.
offset
=
new
Offset
(
0.0
,
mainAxisExtent
);
mainAxisExtent
+=
child
.
size
.
height
;
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
size
=
constraints
.
constrain
(
new
Size
(
constraints
.
maxWidth
,
mainAxisExtent
));
break
;
case
AxisDirection
.
up
:
final
BoxConstraints
innerConstraints
=
new
BoxConstraints
.
tightFor
(
width:
constraints
.
maxWidth
);
while
(
child
!=
null
)
{
child
.
layout
(
innerConstraints
,
parentUsesSize:
true
);
final
ListBodyParentData
childParentData
=
child
.
parentData
;
mainAxisExtent
+=
child
.
size
.
height
;
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
double
position
=
0.0
;
child
=
firstChild
;
while
(
child
!=
null
)
{
final
ListBodyParentData
childParentData
=
child
.
parentData
;
position
+=
child
.
size
.
height
;
childParentData
.
offset
=
new
Offset
(
0.0
,
mainAxisExtent
-
position
);
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
}
size
=
constraints
.
constrain
(
new
Size
(
constraints
.
maxWidth
,
mainAxisExtent
));
break
;
}
assert
(
size
.
isFinite
);
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
description
)
{
super
.
debugFillProperties
(
description
);
description
.
add
(
new
EnumProperty
<
Axis
>(
'mainAxis'
,
mainAxis
));
description
.
add
(
new
EnumProperty
<
Axis
Direction
>(
'axisDirection'
,
axisDirection
));
}
double
_getIntrinsicCrossAxis
(
_ChildSizingFunction
childSize
)
{
...
...
packages/flutter/lib/src/rendering/sliver.dart
View file @
a30b109c
...
...
@@ -41,111 +41,6 @@ enum GrowthDirection {
reverse
,
}
/// A direction along either the horizontal or vertical [Axis].
enum
AxisDirection
{
/// Zero is at the bottom and positive values are above it: ⇈
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A at
/// the bottom and the Z at the top. This is an unusual configuration.
up
,
/// Zero is on the left and positive values are to the right of it: ⇉
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A on
/// the left and the Z on the right. This is the ordinary reading order for a
/// horizontal set of tabs in an English application, for example.
right
,
/// Zero is at the top and positive values are below it: ⇊
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A at
/// the top and the Z at the bottom. This is the ordinary reading order for a
/// vertical list.
down
,
/// Zero is to the right and positive values are to the left of it: ⇇
///
/// Alphabetical content with a [GrowthDirection.forward] would have the A at
/// the right and the Z at the left. This is the ordinary reading order for a
/// horizontal set of tabs in a Hebrew application, for example.
left
,
}
/// Returns the [Axis] that contains the given [AxisDirection].
///
/// Specifically, returns [Axis.vertical] for [AxisDirection.up] and
/// [AxisDirection.down] and returns [Axis.horizontal] for [AxisDirection.left]
/// and [AxisDirection.right].
Axis
axisDirectionToAxis
(
AxisDirection
axisDirection
)
{
assert
(
axisDirection
!=
null
);
switch
(
axisDirection
)
{
case
AxisDirection
.
up
:
case
AxisDirection
.
down
:
return
Axis
.
vertical
;
case
AxisDirection
.
left
:
case
AxisDirection
.
right
:
return
Axis
.
horizontal
;
}
return
null
;
}
/// Returns the [AxisDirection] in which reading occurs in the given [TextDirection].
///
/// Specifically, returns [AxisDirection.left] for [TextDirection.rtl] and
/// [AxisDirection.right] for [TextDirection.ltr].
AxisDirection
textDirectionToAxisDirection
(
TextDirection
textDirection
)
{
assert
(
textDirection
!=
null
);
switch
(
textDirection
)
{
case
TextDirection
.
rtl
:
return
AxisDirection
.
left
;
case
TextDirection
.
ltr
:
return
AxisDirection
.
right
;
}
return
null
;
}
/// Returns the opposite of the given [AxisDirection].
///
/// Specifically, returns [AxisDirection.up] for [AxisDirection.down] (and
/// vice versa), as well as [AxisDirection.left] for [AxisDirection.right] (and
/// vice versa).
///
/// See also:
///
/// * [flipAxis], which does the same thing for [Axis] values.
AxisDirection
flipAxisDirection
(
AxisDirection
axisDirection
)
{
assert
(
axisDirection
!=
null
);
switch
(
axisDirection
)
{
case
AxisDirection
.
up
:
return
AxisDirection
.
down
;
case
AxisDirection
.
right
:
return
AxisDirection
.
left
;
case
AxisDirection
.
down
:
return
AxisDirection
.
up
;
case
AxisDirection
.
left
:
return
AxisDirection
.
right
;
}
return
null
;
}
/// Returns whether travelling along the given axis direction visits coordinates
/// along that axis in numerically decreasing order.
///
/// Specifically, returns true for [AxisDirection.up] and [AxisDirection.left]
/// and false for [AxisDirection.down] for [AxisDirection.right].
bool
axisDirectionIsReversed
(
AxisDirection
axisDirection
)
{
assert
(
axisDirection
!=
null
);
switch
(
axisDirection
)
{
case
AxisDirection
.
up
:
case
AxisDirection
.
left
:
return
true
;
case
AxisDirection
.
down
:
case
AxisDirection
.
right
:
return
false
;
}
return
null
;
}
/// Flips the [AxisDirection] if the [GrowthDirection] is [GrowthDirection.reverse].
///
/// Specifically, returns `axisDirection` if `growthDirection` is
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
a30b109c
...
...
@@ -2116,6 +2116,42 @@ class SliverPadding extends SingleChildRenderObjectWidget {
// LAYOUT NODES
/// Returns the [AxisDirection] in the given [Axis] in the current
/// [Directionality] (or the reverse if `reverse` is true).
///
/// If `axis` is [Axis.vertical], this function returns [AxisDirection.down]
/// unless `reverse` is true, in which case this function returns
/// [AxisDirection.up].
///
/// If `axis` is [Axis.horizontal], this function checks the current
/// [Directionality]. If the current [Directionality] is right-to-left, then
/// this function returns [AxisDirection.left] (unless `reverse` is true, in
/// which case it returns [AxisDirection.right]). Similarly, if the current
/// [Directionality] is left-to-right, then this function returns
/// [AxisDirection.right] (unless `reverse` is true, in which case it returns
/// [AxisDirection.left]).
///
/// This function is used by a number of scrolling widgets (e.g., [ListView],
/// [GridView], [PageView], and [SingleChildScrollView]) as well as [ListBody]
/// to translate their [Axis] and `reverse` properties into a concrete
/// [AxisDirection].
AxisDirection
getAxisDirectionFromAxisReverseAndDirectionality
(
BuildContext
context
,
Axis
axis
,
bool
reverse
,
)
{
switch
(
axis
)
{
case
Axis
.
horizontal
:
assert
(
debugCheckHasDirectionality
(
context
));
final
TextDirection
textDirection
=
Directionality
.
of
(
context
);
final
AxisDirection
axisDirection
=
textDirectionToAxisDirection
(
textDirection
);
return
reverse
?
flipAxisDirection
(
axisDirection
)
:
axisDirection
;
case
Axis
.
vertical
:
return
reverse
?
AxisDirection
.
up
:
AxisDirection
.
down
;
}
return
null
;
}
/// A widget that arranges its children sequentially along a given axis, forcing
/// them to the dimension of the parent in the other axis.
///
...
...
@@ -2142,6 +2178,7 @@ class ListBody extends MultiChildRenderObjectWidget {
ListBody
({
Key
key
,
this
.
mainAxis
:
Axis
.
vertical
,
this
.
reverse
:
false
,
List
<
Widget
>
children:
const
<
Widget
>[],
})
:
assert
(
mainAxis
!=
null
),
super
(
key:
key
,
children:
children
);
...
...
@@ -2149,12 +2186,32 @@ class ListBody extends MultiChildRenderObjectWidget {
/// The direction to use as the main axis.
final
Axis
mainAxis
;
/// Whether the list body positions children in the reading direction.
///
/// For example, if the reading direction is left-to-right and
/// [mainAxis] is [Axis.horizontal], then the list body positions children
/// from left to right when [reverse] is false and from right to left when
/// [reverse] is true.
///
/// Similarly, if [mainAxis] is [Axis.vertical], then the list body positions
/// from top to bottom when [reverse] is false and from bottom to top when
/// [reverse] is true.
///
/// Defaults to false.
final
bool
reverse
;
AxisDirection
_getDirection
(
BuildContext
context
)
{
return
getAxisDirectionFromAxisReverseAndDirectionality
(
context
,
mainAxis
,
reverse
);
}
@override
RenderListBody
createRenderObject
(
BuildContext
context
)
=>
new
RenderListBody
(
mainAxis:
mainAxis
);
RenderListBody
createRenderObject
(
BuildContext
context
)
{
return
new
RenderListBody
(
axisDirection:
_getDirection
(
context
));
}
@override
void
updateRenderObject
(
BuildContext
context
,
RenderListBody
renderObject
)
{
renderObject
.
mainAxis
=
mainAxis
;
renderObject
.
axisDirection
=
_getDirection
(
context
)
;
}
}
...
...
packages/flutter/lib/src/widgets/scroll_view.dart
View file @
a30b109c
...
...
@@ -6,7 +6,6 @@ import 'package:flutter/foundation.dart';
import
'package:flutter/rendering.dart'
;
import
'basic.dart'
;
import
'debug.dart'
;
import
'framework.dart'
;
import
'primary_scroll_controller.dart'
;
import
'scroll_controller.dart'
;
...
...
@@ -179,16 +178,7 @@ abstract class ScrollView extends StatelessWidget {
/// [AxisDirection.right].
@protected
AxisDirection
getDirection
(
BuildContext
context
)
{
switch
(
scrollDirection
)
{
case
Axis
.
horizontal
:
assert
(
debugCheckHasDirectionality
(
context
));
final
TextDirection
textDirection
=
Directionality
.
of
(
context
);
final
AxisDirection
axisDirection
=
textDirectionToAxisDirection
(
textDirection
);
return
reverse
?
flipAxisDirection
(
axisDirection
)
:
axisDirection
;
case
Axis
.
vertical
:
return
reverse
?
AxisDirection
.
up
:
AxisDirection
.
down
;
}
return
null
;
return
getAxisDirectionFromAxisReverseAndDirectionality
(
context
,
scrollDirection
,
reverse
);
}
/// Subclasses should override this method to build the slivers for the inside
...
...
packages/flutter/lib/src/widgets/single_child_scroll_view.dart
View file @
a30b109c
...
...
@@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
import
'package:flutter/rendering.dart'
;
import
'basic.dart'
;
import
'debug.dart'
;
import
'framework.dart'
;
import
'primary_scroll_controller.dart'
;
import
'scroll_controller.dart'
;
...
...
@@ -70,7 +69,7 @@ class SingleChildScrollView extends StatelessWidget {
/// left to right when [reverse] is false and from right to left when
/// [reverse] is true.
///
/// Similarly, if [scrollDirection] is [Axis.vertical], then scroll view
/// Similarly, if [scrollDirection] is [Axis.vertical], then
the
scroll view
/// scrolls from top to bottom when [reverse] is false and from bottom to top
/// when [reverse] is true.
///
...
...
@@ -116,16 +115,7 @@ class SingleChildScrollView extends StatelessWidget {
final
Widget
child
;
AxisDirection
_getDirection
(
BuildContext
context
)
{
switch
(
scrollDirection
)
{
case
Axis
.
horizontal
:
assert
(
debugCheckHasDirectionality
(
context
));
final
TextDirection
textDirection
=
Directionality
.
of
(
context
);
final
AxisDirection
axisDirection
=
textDirectionToAxisDirection
(
textDirection
);
return
reverse
?
flipAxisDirection
(
axisDirection
)
:
axisDirection
;
case
Axis
.
vertical
:
return
reverse
?
AxisDirection
.
up
:
AxisDirection
.
down
;
}
return
null
;
return
getAxisDirectionFromAxisReverseAndDirectionality
(
context
,
scrollDirection
,
reverse
);
}
@override
...
...
packages/flutter/test/rendering/paragraph_intrinsics_test.dart
View file @
a30b109c
...
...
@@ -17,7 +17,7 @@ void main() {
final
RenderListBody
testBlock
=
new
RenderListBody
(
children:
<
RenderBox
>[
paragraph
,
]
]
,
);
final
double
textWidth
=
paragraph
.
getMaxIntrinsicWidth
(
double
.
INFINITY
);
...
...
@@ -52,7 +52,7 @@ void main() {
expect
(
testBlock
.
getMaxIntrinsicHeight
(
0.0
),
equals
(
manyLinesTextHeight
));
// horizontal block (same expectations again)
testBlock
.
mainAxis
=
Axis
.
horizontal
;
testBlock
.
axisDirection
=
AxisDirection
.
right
;
expect
(
testBlock
.
getMinIntrinsicWidth
(
double
.
INFINITY
),
equals
(
wrappedTextWidth
));
expect
(
testBlock
.
getMaxIntrinsicWidth
(
double
.
INFINITY
),
equals
(
textWidth
));
expect
(
testBlock
.
getMinIntrinsicHeight
(
double
.
INFINITY
),
equals
(
oneLineTextHeight
));
...
...
packages/flutter/test/widgets/list_body_test.dart
0 → 100644
View file @
a30b109c
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/widgets.dart'
;
final
List
<
Widget
>
children
=
<
Widget
>[
new
Container
(
width:
200.0
,
height:
150.0
),
new
Container
(
width:
200.0
,
height:
150.0
),
new
Container
(
width:
200.0
,
height:
150.0
),
new
Container
(
width:
200.0
,
height:
150.0
),
];
void
expectRects
(
WidgetTester
tester
,
List
<
Rect
>
expected
)
{
final
Finder
finder
=
find
.
byType
(
Container
);
finder
.
precache
();
final
List
<
Rect
>
actual
=
<
Rect
>[];
for
(
int
i
=
0
;
i
<
expected
.
length
;
++
i
)
{
final
Finder
current
=
finder
.
at
(
i
);
expect
(
current
,
findsOneWidget
);
actual
.
add
(
tester
.
getRect
(
finder
.
at
(
i
)));
}
expect
(()
=>
finder
.
at
(
expected
.
length
),
throwsRangeError
);
expect
(
actual
,
equals
(
expected
));
}
void
main
(
)
{
testWidgets
(
'ListBody down'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Flex
(
direction:
Axis
.
vertical
,
children:
<
Widget
>[
new
ListBody
(
children:
children
)
],
));
expectRects
(
tester
,
<
Rect
>[
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
800.0
,
150.0
),
new
Rect
.
fromLTWH
(
0.0
,
150.0
,
800.0
,
150.0
),
new
Rect
.
fromLTWH
(
0.0
,
300.0
,
800.0
,
150.0
),
new
Rect
.
fromLTWH
(
0.0
,
450.0
,
800.0
,
150.0
),
],
);
});
testWidgets
(
'ListBody up'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Flex
(
direction:
Axis
.
vertical
,
children:
<
Widget
>[
new
ListBody
(
reverse:
true
,
children:
children
)
],
));
expectRects
(
tester
,
<
Rect
>[
new
Rect
.
fromLTWH
(
0.0
,
450.0
,
800.0
,
150.0
),
new
Rect
.
fromLTWH
(
0.0
,
300.0
,
800.0
,
150.0
),
new
Rect
.
fromLTWH
(
0.0
,
150.0
,
800.0
,
150.0
),
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
800.0
,
150.0
),
],
);
});
testWidgets
(
'ListBody right'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Flex
(
textDirection:
TextDirection
.
ltr
,
direction:
Axis
.
horizontal
,
children:
<
Widget
>[
new
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
new
ListBody
(
mainAxis:
Axis
.
horizontal
,
children:
children
),
),
],
));
expectRects
(
tester
,
<
Rect
>[
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
200.0
,
600.0
),
new
Rect
.
fromLTWH
(
200.0
,
0.0
,
200.0
,
600.0
),
new
Rect
.
fromLTWH
(
400.0
,
0.0
,
200.0
,
600.0
),
new
Rect
.
fromLTWH
(
600.0
,
0.0
,
200.0
,
600.0
),
],
);
});
testWidgets
(
'ListBody left'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Flex
(
textDirection:
TextDirection
.
ltr
,
direction:
Axis
.
horizontal
,
children:
<
Widget
>[
new
Directionality
(
textDirection:
TextDirection
.
rtl
,
child:
new
ListBody
(
mainAxis:
Axis
.
horizontal
,
children:
children
),
),
],
));
expectRects
(
tester
,
<
Rect
>[
new
Rect
.
fromLTWH
(
600.0
,
0.0
,
200.0
,
600.0
),
new
Rect
.
fromLTWH
(
400.0
,
0.0
,
200.0
,
600.0
),
new
Rect
.
fromLTWH
(
200.0
,
0.0
,
200.0
,
600.0
),
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
200.0
,
600.0
),
],
);
});
}
packages/flutter_test/lib/src/finders.dart
View file @
a30b109c
...
...
@@ -285,6 +285,10 @@ abstract class Finder {
/// matched by this finder.
Finder
get
last
=>
new
_LastFinder
(
this
);
/// Returns a variant of this finder that only matches the element at the
/// given index matched by this finder.
Finder
at
(
int
index
)
=>
new
_IndexFinder
(
this
,
index
);
/// Returns a variant of this finder that only matches elements reachable by
/// a hit test.
///
...
...
@@ -335,6 +339,22 @@ class _LastFinder extends Finder {
}
}
class
_IndexFinder
extends
Finder
{
_IndexFinder
(
this
.
parent
,
this
.
index
);
final
Finder
parent
;
final
int
index
;
@override
String
get
description
=>
'
${parent.description}
(ignoring all but index
$index
)'
;
@override
Iterable
<
Element
>
apply
(
Iterable
<
Element
>
candidates
)
sync
*
{
yield
parent
.
apply
(
candidates
).
elementAt
(
index
);
}
}
class
_HitTestableFinder
extends
Finder
{
_HitTestableFinder
(
this
.
parent
,
this
.
alignment
);
...
...
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