Commit 15bf91fb authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add RTL support to scrolling (#11842)

This patch includes:

 * SliverPadding
 * ScrollView
 * PageView

Fixes #11764
Fixes #11836
parent 76f24515
...@@ -29,24 +29,49 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -29,24 +29,49 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
/// ///
/// The [padding] argument must not be null and must have non-negative insets. /// The [padding] argument must not be null and must have non-negative insets.
RenderSliverPadding({ RenderSliverPadding({
@required EdgeInsets padding, @required EdgeInsetsGeometry padding,
TextDirection textDirection,
RenderSliver child, RenderSliver child,
}) : assert(padding != null), }) : assert(padding != null),
assert(padding.isNonNegative), assert(padding.isNonNegative),
_padding = padding { _padding = padding,
_textDirection = textDirection {
this.child = child; this.child = child;
_applyUpdate();
}
// The resolved absolute insets.
EdgeInsets _resolvedPadding;
void _applyUpdate() {
final EdgeInsets resolvedPadding = padding.resolve(textDirection);
assert(resolvedPadding.isNonNegative);
if (_resolvedPadding != resolvedPadding) {
_resolvedPadding = resolvedPadding;
markNeedsLayout();
}
} }
/// The amount to pad the child in each dimension. /// The amount to pad the child in each dimension.
EdgeInsets get padding => _padding; EdgeInsetsGeometry get padding => _padding;
EdgeInsets _padding; EdgeInsetsGeometry _padding;
set padding(EdgeInsets value) { set padding(EdgeInsetsGeometry value) {
assert(value != null); assert(value != null);
assert(value.isNonNegative); assert(padding.isNonNegative);
if (_padding == value) if (_padding == value)
return; return;
_padding = value; _padding = value;
markNeedsLayout(); _applyUpdate();
}
/// The text direction with which to resolve [padding].
TextDirection get textDirection => _textDirection;
TextDirection _textDirection;
set textDirection(TextDirection value) {
if (_textDirection == value)
return;
_textDirection = value;
_applyUpdate();
} }
/// The padding in the scroll direction on the side nearest the 0.0 scroll direction. /// The padding in the scroll direction on the side nearest the 0.0 scroll direction.
...@@ -59,13 +84,13 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -59,13 +84,13 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert(constraints.growthDirection != null); assert(constraints.growthDirection != null);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up: case AxisDirection.up:
return padding.bottom; return _resolvedPadding.bottom;
case AxisDirection.right: case AxisDirection.right:
return padding.left; return _resolvedPadding.left;
case AxisDirection.down: case AxisDirection.down:
return padding.top; return _resolvedPadding.top;
case AxisDirection.left: case AxisDirection.left:
return padding.right; return _resolvedPadding.right;
} }
return null; return null;
} }
...@@ -80,13 +105,13 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -80,13 +105,13 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert(constraints.growthDirection != null); assert(constraints.growthDirection != null);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up: case AxisDirection.up:
return padding.top; return _resolvedPadding.top;
case AxisDirection.right: case AxisDirection.right:
return padding.right; return _resolvedPadding.right;
case AxisDirection.down: case AxisDirection.down:
return padding.bottom; return _resolvedPadding.bottom;
case AxisDirection.left: case AxisDirection.left:
return padding.left; return _resolvedPadding.left;
} }
return null; return null;
} }
...@@ -100,7 +125,7 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -100,7 +125,7 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
double get mainAxisPadding { double get mainAxisPadding {
assert(constraints != null); assert(constraints != null);
assert(constraints.axis != null); assert(constraints.axis != null);
return padding.along(constraints.axis); return _resolvedPadding.along(constraints.axis);
} }
/// The total padding in the cross-axis direction. (In other words, for a /// The total padding in the cross-axis direction. (In other words, for a
...@@ -114,9 +139,9 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -114,9 +139,9 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert(constraints.axis != null); assert(constraints.axis != null);
switch (constraints.axis) { switch (constraints.axis) {
case Axis.horizontal: case Axis.horizontal:
return padding.vertical; return _resolvedPadding.vertical;
case Axis.vertical: case Axis.vertical:
return padding.horizontal; return _resolvedPadding.horizontal;
} }
return null; return null;
} }
...@@ -183,16 +208,16 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -183,16 +208,16 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert(constraints.growthDirection != null); assert(constraints.growthDirection != null);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up: case AxisDirection.up:
childParentData.paintOffset = new Offset(padding.left, calculatePaintOffset(constraints, from: padding.bottom + childLayoutGeometry.scrollExtent, to: padding.bottom + childLayoutGeometry.scrollExtent + padding.top)); childParentData.paintOffset = new Offset(_resolvedPadding.left, calculatePaintOffset(constraints, from: _resolvedPadding.bottom + childLayoutGeometry.scrollExtent, to: _resolvedPadding.bottom + childLayoutGeometry.scrollExtent + _resolvedPadding.top));
break; break;
case AxisDirection.right: case AxisDirection.right:
childParentData.paintOffset = new Offset(calculatePaintOffset(constraints, from: 0.0, to: padding.left), padding.top); childParentData.paintOffset = new Offset(calculatePaintOffset(constraints, from: 0.0, to: _resolvedPadding.left), _resolvedPadding.top);
break; break;
case AxisDirection.down: case AxisDirection.down:
childParentData.paintOffset = new Offset(padding.left, calculatePaintOffset(constraints, from: 0.0, to: padding.top)); childParentData.paintOffset = new Offset(_resolvedPadding.left, calculatePaintOffset(constraints, from: 0.0, to: _resolvedPadding.top));
break; break;
case AxisDirection.left: case AxisDirection.left:
childParentData.paintOffset = new Offset(calculatePaintOffset(constraints, from: padding.right + childLayoutGeometry.scrollExtent, to: padding.right + childLayoutGeometry.scrollExtent + padding.left), padding.top); childParentData.paintOffset = new Offset(calculatePaintOffset(constraints, from: _resolvedPadding.right + childLayoutGeometry.scrollExtent, to: _resolvedPadding.right + childLayoutGeometry.scrollExtent + _resolvedPadding.left), _resolvedPadding.top);
break; break;
} }
assert(childParentData.paintOffset != null); assert(childParentData.paintOffset != null);
...@@ -226,10 +251,10 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -226,10 +251,10 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up: case AxisDirection.up:
case AxisDirection.down: case AxisDirection.down:
return padding.left; return _resolvedPadding.left;
case AxisDirection.left: case AxisDirection.left:
case AxisDirection.right: case AxisDirection.right:
return padding.top; return _resolvedPadding.top;
} }
return null; return null;
} }
...@@ -279,4 +304,11 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R ...@@ -279,4 +304,11 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
return true; return true;
}); });
} }
@override
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
description.add(new DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding));
description.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
}
} }
...@@ -2063,22 +2063,27 @@ class SliverPadding extends SingleChildRenderObjectWidget { ...@@ -2063,22 +2063,27 @@ class SliverPadding extends SingleChildRenderObjectWidget {
super(key: key, child: sliver); super(key: key, child: sliver);
/// The amount of space by which to inset the child sliver. /// The amount of space by which to inset the child sliver.
final EdgeInsets padding; final EdgeInsetsGeometry padding;
// TODO(ianh): RTL
@override @override
RenderSliverPadding createRenderObject(BuildContext context) => new RenderSliverPadding(padding: padding); RenderSliverPadding createRenderObject(BuildContext context) {
return new RenderSliverPadding(
padding: padding,
textDirection: Directionality.of(context),
);
}
@override @override
void updateRenderObject(BuildContext context, RenderSliverPadding renderObject) { void updateRenderObject(BuildContext context, RenderSliverPadding renderObject) {
renderObject.padding = padding; renderObject
..padding = padding
..textDirection = Directionality.of(context);
} }
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder description) { void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description); super.debugFillProperties(description);
description.add(new DiagnosticsProperty<EdgeInsets>('padding', padding)); description.add(new DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding));
} }
} }
......
...@@ -449,10 +449,17 @@ class _PageViewState extends State<PageView> { ...@@ -449,10 +449,17 @@ class _PageViewState extends State<PageView> {
} }
AxisDirection _getDirection(BuildContext context) { AxisDirection _getDirection(BuildContext context) {
// TODO(abarth): Consider reading direction.
switch (widget.scrollDirection) { switch (widget.scrollDirection) {
case Axis.horizontal: case Axis.horizontal:
final TextDirection textDirection = Directionality.of(context);
assert(textDirection != null);
switch (textDirection) {
case TextDirection.rtl:
return widget.reverse ? AxisDirection.right : AxisDirection.left;
case TextDirection.ltr:
return widget.reverse ? AxisDirection.left : AxisDirection.right; return widget.reverse ? AxisDirection.left : AxisDirection.right;
}
return null;
case Axis.vertical: case Axis.vertical:
return widget.reverse ? AxisDirection.up : AxisDirection.down; return widget.reverse ? AxisDirection.up : AxisDirection.down;
} }
......
...@@ -170,13 +170,25 @@ abstract class ScrollView extends StatelessWidget { ...@@ -170,13 +170,25 @@ abstract class ScrollView extends StatelessWidget {
/// Combines the [scrollDirection] with the [reverse] boolean to obtain the /// Combines the [scrollDirection] with the [reverse] boolean to obtain the
/// concrete [AxisDirection]. /// concrete [AxisDirection].
/// ///
/// In the future, this function will also consider the reading direction. /// If the [scrollDirection] is [Axis.horizontal], the ambient
/// [Directionality] is also consided when selecting the concrete
/// [AxisDirection]. For example, if the ambient [Directionality] is
/// [TextDirection.rtl], then the non-reversed [AxisDirection] is
/// [AxisDirection.left] and the reversed [AxisDirection] is
/// [AxisDirection.right].
@protected @protected
AxisDirection getDirection(BuildContext context) { AxisDirection getDirection(BuildContext context) {
// TODO(abarth): Consider reading direction.
switch (scrollDirection) { switch (scrollDirection) {
case Axis.horizontal: case Axis.horizontal:
final TextDirection textDirection = Directionality.of(context);
assert(textDirection != null);
switch (textDirection) {
case TextDirection.rtl:
return reverse ? AxisDirection.right : AxisDirection.left;
case TextDirection.ltr:
return reverse ? AxisDirection.left : AxisDirection.right; return reverse ? AxisDirection.left : AxisDirection.right;
}
return null;
case Axis.vertical: case Axis.vertical:
return reverse ? AxisDirection.up : AxisDirection.down; return reverse ? AxisDirection.up : AxisDirection.down;
} }
...@@ -367,7 +379,7 @@ abstract class BoxScrollView extends ScrollView { ...@@ -367,7 +379,7 @@ abstract class BoxScrollView extends ScrollView {
); );
/// The amount of space by which to inset the children. /// The amount of space by which to inset the children.
final EdgeInsets padding; final EdgeInsetsGeometry padding;
@override @override
List<Widget> buildSlivers(BuildContext context) { List<Widget> buildSlivers(BuildContext context) {
...@@ -384,7 +396,7 @@ abstract class BoxScrollView extends ScrollView { ...@@ -384,7 +396,7 @@ abstract class BoxScrollView extends ScrollView {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder description) { void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description); super.debugFillProperties(description);
description.add(new DiagnosticsProperty<EdgeInsets>('padding', padding, defaultValue: null)); description.add(new DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
} }
} }
...@@ -545,7 +557,7 @@ class ListView extends BoxScrollView { ...@@ -545,7 +557,7 @@ class ListView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
this.itemExtent, this.itemExtent,
bool addAutomaticKeepAlives: true, bool addAutomaticKeepAlives: true,
bool addRepaintBoundaries: true, bool addRepaintBoundaries: true,
...@@ -597,7 +609,7 @@ class ListView extends BoxScrollView { ...@@ -597,7 +609,7 @@ class ListView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
this.itemExtent, this.itemExtent,
@required IndexedWidgetBuilder itemBuilder, @required IndexedWidgetBuilder itemBuilder,
int itemCount, int itemCount,
...@@ -631,7 +643,7 @@ class ListView extends BoxScrollView { ...@@ -631,7 +643,7 @@ class ListView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
this.itemExtent, this.itemExtent,
@required this.childrenDelegate, @required this.childrenDelegate,
}) : assert(childrenDelegate != null), }) : assert(childrenDelegate != null),
...@@ -825,7 +837,7 @@ class GridView extends BoxScrollView { ...@@ -825,7 +837,7 @@ class GridView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
@required this.gridDelegate, @required this.gridDelegate,
bool addAutomaticKeepAlives: true, bool addAutomaticKeepAlives: true,
bool addRepaintBoundaries: true, bool addRepaintBoundaries: true,
...@@ -874,7 +886,7 @@ class GridView extends BoxScrollView { ...@@ -874,7 +886,7 @@ class GridView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
@required this.gridDelegate, @required this.gridDelegate,
@required IndexedWidgetBuilder itemBuilder, @required IndexedWidgetBuilder itemBuilder,
int itemCount, int itemCount,
...@@ -913,7 +925,7 @@ class GridView extends BoxScrollView { ...@@ -913,7 +925,7 @@ class GridView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
@required this.gridDelegate, @required this.gridDelegate,
@required this.childrenDelegate, @required this.childrenDelegate,
}) : assert(gridDelegate != null), }) : assert(gridDelegate != null),
...@@ -951,7 +963,7 @@ class GridView extends BoxScrollView { ...@@ -951,7 +963,7 @@ class GridView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
@required int crossAxisCount, @required int crossAxisCount,
double mainAxisSpacing: 0.0, double mainAxisSpacing: 0.0,
double crossAxisSpacing: 0.0, double crossAxisSpacing: 0.0,
...@@ -1002,7 +1014,7 @@ class GridView extends BoxScrollView { ...@@ -1002,7 +1014,7 @@ class GridView extends BoxScrollView {
bool primary, bool primary,
ScrollPhysics physics, ScrollPhysics physics,
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsetsGeometry padding,
@required double maxCrossAxisExtent, @required double maxCrossAxisExtent,
double mainAxisSpacing: 0.0, double mainAxisSpacing: 0.0,
double crossAxisSpacing: 0.0, double crossAxisSpacing: 0.0,
......
...@@ -77,7 +77,7 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -77,7 +77,7 @@ class SingleChildScrollView extends StatelessWidget {
final bool reverse; final bool reverse;
/// The amount of space by which to inset the child. /// The amount of space by which to inset the child.
final EdgeInsets padding; final EdgeInsetsGeometry padding;
/// An object that can be used to control the position to which this scroll /// An object that can be used to control the position to which this scroll
/// view is scrolled. /// view is scrolled.
...@@ -99,7 +99,7 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -99,7 +99,7 @@ class SingleChildScrollView extends StatelessWidget {
/// On iOS, this identifies the scroll view that will scroll to top in /// On iOS, this identifies the scroll view that will scroll to top in
/// response to a tap in the status bar. /// response to a tap in the status bar.
/// ///
/// Defaults to true when `scrollDirection` is vertical and `controller` is /// Defaults to true when [scrollDirection] is vertical and [controller] is
/// not specified. /// not specified.
final bool primary; final bool primary;
...@@ -115,10 +115,17 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -115,10 +115,17 @@ class SingleChildScrollView extends StatelessWidget {
final Widget child; final Widget child;
AxisDirection _getDirection(BuildContext context) { AxisDirection _getDirection(BuildContext context) {
// TODO(abarth): Consider reading direction.
switch (scrollDirection) { switch (scrollDirection) {
case Axis.horizontal: case Axis.horizontal:
final TextDirection textDirection = Directionality.of(context);
assert(textDirection != null);
switch (textDirection) {
case TextDirection.rtl:
return reverse ? AxisDirection.right : AxisDirection.left;
case TextDirection.ltr:
return reverse ? AxisDirection.left : AxisDirection.right; return reverse ? AxisDirection.left : AxisDirection.right;
}
return null;
case Axis.vertical: case Axis.vertical:
return reverse ? AxisDirection.up : AxisDirection.down; return reverse ? AxisDirection.up : AxisDirection.down;
} }
......
...@@ -802,8 +802,9 @@ void main() { ...@@ -802,8 +802,9 @@ void main() {
length: 3, length: 3,
); );
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new SizedBox.expand( textDirection: TextDirection.ltr,
child: new SizedBox.expand(
child: new Center( child: new Center(
child: new SizedBox( child: new SizedBox(
width: 400.0, width: 400.0,
...@@ -819,7 +820,7 @@ void main() { ...@@ -819,7 +820,7 @@ void main() {
), ),
), ),
), ),
); ));
expect(tabController.index, 1); expect(tabController.index, 1);
...@@ -848,8 +849,9 @@ void main() { ...@@ -848,8 +849,9 @@ void main() {
length: 3, length: 3,
); );
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new SizedBox.expand( textDirection: TextDirection.ltr,
child: new SizedBox.expand(
child: new Center( child: new Center(
child: new SizedBox( child: new SizedBox(
width: 400.0, width: 400.0,
...@@ -866,7 +868,7 @@ void main() { ...@@ -866,7 +868,7 @@ void main() {
), ),
), ),
), ),
); ));
expect(tabController.index, 1); expect(tabController.index, 1);
......
...@@ -33,8 +33,9 @@ void main() { ...@@ -33,8 +33,9 @@ void main() {
testWidgets('Aspect ratio infinite width', (WidgetTester tester) async { testWidgets('Aspect ratio infinite width', (WidgetTester tester) async {
final Key childKey = new UniqueKey(); final Key childKey = new UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new Center( textDirection: TextDirection.ltr,
child: new Center(
child: new SingleChildScrollView( child: new SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: new AspectRatio( child: new AspectRatio(
...@@ -45,7 +46,7 @@ void main() { ...@@ -45,7 +46,7 @@ void main() {
) )
) )
) )
); ));
final RenderBox box = tester.renderObject(find.byKey(childKey)); final RenderBox box = tester.renderObject(find.byKey(childKey));
expect(box.size, equals(const Size(1200.0, 600.0))); expect(box.size, equals(const Size(1200.0, 600.0)));
}); });
......
...@@ -42,7 +42,9 @@ Widget buildTest({ double startToEndThreshold }) { ...@@ -42,7 +42,9 @@ Widget buildTest({ double startToEndThreshold }) {
); );
} }
return new Container( return new Directionality(
textDirection: TextDirection.ltr,
child: new Container(
padding: const EdgeInsets.all(10.0), padding: const EdgeInsets.all(10.0),
child: new ListView( child: new ListView(
scrollDirection: scrollDirection, scrollDirection: scrollDirection,
...@@ -51,6 +53,7 @@ Widget buildTest({ double startToEndThreshold }) { ...@@ -51,6 +53,7 @@ Widget buildTest({ double startToEndThreshold }) {
.where((int i) => !dismissedItems.contains(i)) .where((int i) => !dismissedItems.contains(i))
.map(buildDismissibleItem).toList(), .map(buildDismissibleItem).toList(),
), ),
),
); );
}, },
); );
......
...@@ -11,7 +11,9 @@ import 'package:flutter/widgets.dart'; ...@@ -11,7 +11,9 @@ import 'package:flutter/widgets.dart';
Finder findKey(int i) => find.byKey(new ValueKey<int>(i)); Finder findKey(int i) => find.byKey(new ValueKey<int>(i));
Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse: false }) { Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse: false }) {
return new Center( return new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 600.0, width: 600.0,
height: 400.0, height: 400.0,
...@@ -32,11 +34,14 @@ Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse: false }) ...@@ -32,11 +34,14 @@ Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse: false })
), ),
), ),
), ),
),
); );
} }
Widget buildListView(Axis scrollDirection, { bool reverse: false, bool shrinkWrap: false }) { Widget buildListView(Axis scrollDirection, { bool reverse: false, bool shrinkWrap: false }) {
return new Center( return new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 600.0, width: 600.0,
height: 400.0, height: 400.0,
...@@ -55,6 +60,7 @@ Widget buildListView(Axis scrollDirection, { bool reverse: false, bool shrinkWra ...@@ -55,6 +60,7 @@ Widget buildListView(Axis scrollDirection, { bool reverse: false, bool shrinkWra
], ],
), ),
), ),
),
); );
} }
...@@ -423,8 +429,9 @@ void main() { ...@@ -423,8 +429,9 @@ void main() {
await tester.pump(); await tester.pump();
} }
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new Center( textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 600.0, width: 600.0,
height: 400.0, height: 400.0,
...@@ -454,7 +461,7 @@ void main() { ...@@ -454,7 +461,7 @@ void main() {
), ),
), ),
) )
); ));
await prepare(321.0); await prepare(321.0);
Scrollable.ensureVisible(findContext(0)); Scrollable.ensureVisible(findContext(0));
......
...@@ -126,8 +126,9 @@ void main() { ...@@ -126,8 +126,9 @@ void main() {
testWidgets('GridView large scroll jump', (WidgetTester tester) async { testWidgets('GridView large scroll jump', (WidgetTester tester) async {
final List<int> log = <int>[]; final List<int> log = <int>[];
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new GridView.extent( textDirection: TextDirection.ltr,
child: new GridView.extent(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
maxCrossAxisExtent: 200.0, maxCrossAxisExtent: 200.0,
childAspectRatio: 0.75, childAspectRatio: 0.75,
...@@ -142,7 +143,7 @@ void main() { ...@@ -142,7 +143,7 @@ void main() {
); );
}), }),
), ),
); ));
expect(tester.getSize(find.text('4')), equals(const Size(200.0 / 0.75, 200.0))); expect(tester.getSize(find.text('4')), equals(const Size(200.0 / 0.75, 200.0)));
......
...@@ -127,15 +127,18 @@ void main() { ...@@ -127,15 +127,18 @@ void main() {
); );
}; };
FlipWidget buildWidget() { Widget buildWidget() {
return new FlipWidget( return new Directionality(
textDirection: TextDirection.ltr,
child: new FlipWidget(
left: new ListView.builder( left: new ListView.builder(
controller: new ScrollController(initialScrollOffset: 300.0), controller: new ScrollController(initialScrollOffset: 300.0),
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
itemExtent: 200.0, itemExtent: 200.0,
scrollDirection: Axis.horizontal scrollDirection: Axis.horizontal,
),
right: const Text('Not Today'),
), ),
right: const Text('Not Today')
); );
} }
......
...@@ -117,13 +117,16 @@ void main() { ...@@ -117,13 +117,16 @@ void main() {
}; };
Widget builder() { Widget builder() {
return new FlipWidget( return new Directionality(
textDirection: TextDirection.ltr,
child: new FlipWidget(
left: new ListView.builder( left: new ListView.builder(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
controller: new ScrollController(initialScrollOffset: 300.0), controller: new ScrollController(initialScrollOffset: 300.0),
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
), ),
right: const Text('Not Today'), right: const Text('Not Today'),
),
); );
} }
......
...@@ -263,15 +263,16 @@ void main() { ...@@ -263,15 +263,16 @@ void main() {
expect(controller.mostRecentlyUpdatedPosition, isNull); expect(controller.mostRecentlyUpdatedPosition, isNull);
expect(controller.initialScrollOffset, 0.0); expect(controller.initialScrollOffset, 0.0);
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new PageView( textDirection: TextDirection.ltr,
child: new PageView(
children: <Widget>[ children: <Widget>[
buildTest(controller: controller, title: 'Page0'), buildTest(controller: controller, title: 'Page0'),
buildTest(controller: controller, title: 'Page1'), buildTest(controller: controller, title: 'Page1'),
buildTest(controller: controller, title: 'Page2'), buildTest(controller: controller, title: 'Page2'),
], ],
), ),
); ));
// Initially Page0 is visible and Page0's appbar is fully expanded (height = 200.0). // Initially Page0 is visible and Page0's appbar is fully expanded (height = 200.0).
expect(find.text('Page0'), findsOneWidget); expect(find.text('Page0'), findsOneWidget);
......
...@@ -180,15 +180,16 @@ void main() { ...@@ -180,15 +180,16 @@ void main() {
}); });
testWidgets('Overscroll horizontally', (WidgetTester tester) async { testWidgets('Overscroll horizontally', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new CustomScrollView( textDirection: TextDirection.ltr,
child: new CustomScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
slivers: <Widget>[ slivers: <Widget>[
const SliverToBoxAdapter(child: const SizedBox(height: 20.0)), const SliverToBoxAdapter(child: const SizedBox(height: 20.0)),
], ],
), ),
); ));
final RenderObject painter = tester.renderObject(find.byType(CustomPaint)); final RenderObject painter = tester.renderObject(find.byType(CustomPaint));
await slowDrag(tester, const Offset(200.0, 200.0), const Offset(5.0, 0.0)); await slowDrag(tester, const Offset(200.0, 200.0), const Offset(5.0, 0.0));
expect(painter, paints..rotate(angle: math.PI / 2.0)..circle()..saveRestore()); expect(painter, paints..rotate(angle: math.PI / 2.0)..circle()..saveRestore());
...@@ -202,8 +203,9 @@ void main() { ...@@ -202,8 +203,9 @@ void main() {
}); });
testWidgets('Nested overscrolls do not throw exceptions', (WidgetTester tester) async { testWidgets('Nested overscrolls do not throw exceptions', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new PageView( textDirection: TextDirection.ltr,
child: new PageView(
children: <Widget>[ children: <Widget>[
new ListView( new ListView(
children: <Widget>[ children: <Widget>[
...@@ -216,7 +218,7 @@ void main() { ...@@ -216,7 +218,7 @@ void main() {
), ),
], ],
), ),
); ));
await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 2000.0)); await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 2000.0));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -225,8 +227,9 @@ void main() { ...@@ -225,8 +227,9 @@ void main() {
testWidgets('Changing settings', (WidgetTester tester) async { testWidgets('Changing settings', (WidgetTester tester) async {
RenderObject painter; RenderObject painter;
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new ScrollConfiguration( textDirection: TextDirection.ltr,
child: new ScrollConfiguration(
behavior: new TestScrollBehavior1(), behavior: new TestScrollBehavior1(),
child: new CustomScrollView( child: new CustomScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -237,15 +240,16 @@ void main() { ...@@ -237,15 +240,16 @@ void main() {
], ],
), ),
), ),
); ));
painter = tester.renderObject(find.byType(CustomPaint)); painter = tester.renderObject(find.byType(CustomPaint));
await slowDrag(tester, const Offset(200.0, 200.0), const Offset(5.0, 0.0)); await slowDrag(tester, const Offset(200.0, 200.0), const Offset(5.0, 0.0));
expect(painter, paints..rotate(angle: math.PI / 2.0)..circle(color: const Color(0x0A00FF00))); expect(painter, paints..rotate(angle: math.PI / 2.0)..circle(color: const Color(0x0A00FF00)));
expect(painter, isNot(paints..circle()..circle())); expect(painter, isNot(paints..circle()..circle()));
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new ScrollConfiguration( textDirection: TextDirection.ltr,
child: new ScrollConfiguration(
behavior: new TestScrollBehavior2(), behavior: new TestScrollBehavior2(),
child: new CustomScrollView( child: new CustomScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -255,7 +259,7 @@ void main() { ...@@ -255,7 +259,7 @@ void main() {
], ],
), ),
), ),
); ));
painter = tester.renderObject(find.byType(CustomPaint)); painter = tester.renderObject(find.byType(CustomPaint));
await slowDrag(tester, const Offset(200.0, 200.0), const Offset(5.0, 0.0)); await slowDrag(tester, const Offset(200.0, 200.0), const Offset(5.0, 0.0));
expect(painter, paints..rotate(angle: math.PI / 2.0)..circle(color: const Color(0x0A0000FF))..saveRestore()); expect(painter, paints..rotate(angle: math.PI / 2.0)..circle(color: const Color(0x0A0000FF))..saveRestore());
......
...@@ -14,7 +14,9 @@ void main() { ...@@ -14,7 +14,9 @@ void main() {
testWidgets('PageView control test', (WidgetTester tester) async { testWidgets('PageView control test', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
await tester.pumpWidget(new PageView( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new PageView(
children: kStates.map<Widget>((String state) { children: kStates.map<Widget>((String state) {
return new GestureDetector( return new GestureDetector(
onTap: () { onTap: () {
...@@ -27,6 +29,7 @@ void main() { ...@@ -27,6 +29,7 @@ void main() {
), ),
); );
}).toList(), }).toList(),
),
)); ));
await tester.tap(find.text('Alabama')); await tester.tap(find.text('Alabama'));
...@@ -111,7 +114,9 @@ void main() { ...@@ -111,7 +114,9 @@ void main() {
testWidgets('PageController control test', (WidgetTester tester) async { testWidgets('PageController control test', (WidgetTester tester) async {
final PageController controller = new PageController(initialPage: 4); final PageController controller = new PageController(initialPage: 4);
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 600.0, width: 600.0,
height: 400.0, height: 400.0,
...@@ -120,6 +125,7 @@ void main() { ...@@ -120,6 +125,7 @@ void main() {
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
), ),
),
)); ));
expect(find.text('California'), findsOneWidget); expect(find.text('California'), findsOneWidget);
...@@ -129,7 +135,9 @@ void main() { ...@@ -129,7 +135,9 @@ void main() {
expect(find.text('Colorado'), findsOneWidget); expect(find.text('Colorado'), findsOneWidget);
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 300.0, width: 300.0,
height: 400.0, height: 400.0,
...@@ -138,6 +146,7 @@ void main() { ...@@ -138,6 +146,7 @@ void main() {
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
), ),
),
)); ));
expect(find.text('Colorado'), findsOneWidget); expect(find.text('Colorado'), findsOneWidget);
...@@ -149,13 +158,16 @@ void main() { ...@@ -149,13 +158,16 @@ void main() {
}); });
testWidgets('PageController page stability', (WidgetTester tester) async { testWidgets('PageController page stability', (WidgetTester tester) async {
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 600.0, width: 600.0,
height: 400.0, height: 400.0,
child: new PageView( child: new PageView(
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
)
), ),
)); ));
...@@ -166,7 +178,9 @@ void main() { ...@@ -166,7 +178,9 @@ void main() {
expect(find.text('Arizona'), findsOneWidget); expect(find.text('Arizona'), findsOneWidget);
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 250.0, width: 250.0,
height: 100.0, height: 100.0,
...@@ -174,11 +188,14 @@ void main() { ...@@ -174,11 +188,14 @@ void main() {
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
), ),
),
)); ));
expect(find.text('Arizona'), findsOneWidget); expect(find.text('Arizona'), findsOneWidget);
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 450.0, width: 450.0,
height: 400.0, height: 400.0,
...@@ -186,13 +203,16 @@ void main() { ...@@ -186,13 +203,16 @@ void main() {
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
), ),
),
)); ));
expect(find.text('Arizona'), findsOneWidget); expect(find.text('Arizona'), findsOneWidget);
}); });
testWidgets('PageView in zero-size container', (WidgetTester tester) async { testWidgets('PageView in zero-size container', (WidgetTester tester) async {
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 0.0, width: 0.0,
height: 0.0, height: 0.0,
...@@ -200,11 +220,14 @@ void main() { ...@@ -200,11 +220,14 @@ void main() {
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
), ),
),
)); ));
expect(find.text('Alabama'), findsOneWidget); expect(find.text('Alabama'), findsOneWidget);
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new SizedBox( child: new SizedBox(
width: 200.0, width: 200.0,
height: 200.0, height: 200.0,
...@@ -212,6 +235,7 @@ void main() { ...@@ -212,6 +235,7 @@ void main() {
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
), ),
), ),
),
)); ));
expect(find.text('Alabama'), findsOneWidget); expect(find.text('Alabama'), findsOneWidget);
...@@ -219,9 +243,12 @@ void main() { ...@@ -219,9 +243,12 @@ void main() {
testWidgets('Page changes at halfway point', (WidgetTester tester) async { testWidgets('Page changes at halfway point', (WidgetTester tester) async {
final List<int> log = <int>[]; final List<int> log = <int>[];
await tester.pumpWidget(new PageView( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new PageView(
onPageChanged: log.add, onPageChanged: log.add,
children: kStates.map<Widget>((String state) => new Text(state)).toList(), children: kStates.map<Widget>((String state) => new Text(state)).toList(),
),
)); ));
expect(log, isEmpty); expect(log, isEmpty);
...@@ -268,7 +295,9 @@ void main() { ...@@ -268,7 +295,9 @@ void main() {
PageController controller = new PageController(viewportFraction: 7/8); PageController controller = new PageController(viewportFraction: 7/8);
Widget build(PageController controller) { Widget build(PageController controller) {
return new PageView.builder( return new Directionality(
textDirection: TextDirection.ltr,
child: new PageView.builder(
controller: controller, controller: controller,
itemCount: kStates.length, itemCount: kStates.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
...@@ -280,6 +309,7 @@ void main() { ...@@ -280,6 +309,7 @@ void main() {
child: new Text(kStates[index]), child: new Text(kStates[index]),
); );
}, },
),
); );
} }
...@@ -308,7 +338,9 @@ void main() { ...@@ -308,7 +338,9 @@ void main() {
final PageController controller = new PageController(viewportFraction: 1/8); final PageController controller = new PageController(viewportFraction: 1/8);
Widget build(PageController controller) { Widget build(PageController controller) {
return new PageView.builder( return new Directionality(
textDirection: TextDirection.ltr,
child: new PageView.builder(
controller: controller, controller: controller,
itemCount: kStates.length, itemCount: kStates.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
...@@ -320,6 +352,7 @@ void main() { ...@@ -320,6 +352,7 @@ void main() {
child: new Text(kStates[index]), child: new Text(kStates[index]),
); );
}, },
),
); );
} }
...@@ -350,7 +383,9 @@ void main() { ...@@ -350,7 +383,9 @@ void main() {
new PageController(viewportFraction: 5/4); new PageController(viewportFraction: 5/4);
Widget build(PageController controller) { Widget build(PageController controller) {
return new PageView.builder( return new Directionality(
textDirection: TextDirection.ltr,
child: new PageView.builder(
controller: controller, controller: controller,
itemCount: kStates.length, itemCount: kStates.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
...@@ -362,6 +397,7 @@ void main() { ...@@ -362,6 +397,7 @@ void main() {
child: new Text(kStates[index]), child: new Text(kStates[index]),
); );
}, },
),
); );
} }
...@@ -383,13 +419,16 @@ void main() { ...@@ -383,13 +419,16 @@ void main() {
); );
int changeIndex = 0; int changeIndex = 0;
Widget build() { Widget build() {
return new PageView( return new Directionality(
textDirection: TextDirection.ltr,
child: new PageView(
children: children:
kStates.map<Widget>((String state) => new Text(state)).toList(), kStates.map<Widget>((String state) => new Text(state)).toList(),
controller: controller, controller: controller,
onPageChanged: (int page) { onPageChanged: (int page) {
changeIndex = page; changeIndex = page;
}, },
),
); );
} }
...@@ -405,8 +444,9 @@ void main() { ...@@ -405,8 +444,9 @@ void main() {
(WidgetTester tester) async { (WidgetTester tester) async {
final PageController controller = new PageController(); final PageController controller = new PageController();
final PageStorageBucket bucket = new PageStorageBucket(); final PageStorageBucket bucket = new PageStorageBucket();
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new PageStorage( textDirection: TextDirection.ltr,
child: new PageStorage(
bucket: bucket, bucket: bucket,
child: new PageView( child: new PageView(
key: const PageStorageKey<String>('PageView'), key: const PageStorageKey<String>('PageView'),
...@@ -418,7 +458,7 @@ void main() { ...@@ -418,7 +458,7 @@ void main() {
], ],
), ),
), ),
); ));
expect(controller.page, 0); expect(controller.page, 0);
controller.jumpToPage(2); controller.jumpToPage(2);
expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 1); expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 1);
...@@ -430,8 +470,9 @@ void main() { ...@@ -430,8 +470,9 @@ void main() {
), ),
); );
expect(() => controller.page, throwsAssertionError); expect(() => controller.page, throwsAssertionError);
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new PageStorage( textDirection: TextDirection.ltr,
child: new PageStorage(
bucket: bucket, bucket: bucket,
child: new PageView( child: new PageView(
key: const PageStorageKey<String>('PageView'), key: const PageStorageKey<String>('PageView'),
...@@ -443,12 +484,13 @@ void main() { ...@@ -443,12 +484,13 @@ void main() {
], ],
), ),
), ),
); ));
expect(controller.page, 2); expect(controller.page, 2);
final PageController controller2 = new PageController(keepPage: false); final PageController controller2 = new PageController(keepPage: false);
await tester.pumpWidget( await tester.pumpWidget(new Directionality(
new PageStorage( textDirection: TextDirection.ltr,
child: new PageStorage(
bucket: bucket, bucket: bucket,
child: new PageView( child: new PageView(
key: const PageStorageKey<String>('Check it again against your list and see consistency!'), key: const PageStorageKey<String>('Check it again against your list and see consistency!'),
...@@ -460,7 +502,7 @@ void main() { ...@@ -460,7 +502,7 @@ void main() {
], ],
), ),
), ),
); ));
expect(controller2.page, 0); expect(controller2.page, 0);
}); });
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
Size pageSize = const Size(600.0, 300.0); Size pageSize = const Size(600.0, 300.0);
const List<int> defaultPages = const <int>[0, 1, 2, 3, 4, 5]; const List<int> defaultPages = const <int>[0, 1, 2, 3, 4, 5];
...@@ -22,7 +23,8 @@ Widget buildPage(int page) { ...@@ -22,7 +23,8 @@ Widget buildPage(int page) {
Widget buildFrame({ Widget buildFrame({
bool reverse: false, bool reverse: false,
List<int> pages: defaultPages List<int> pages: defaultPages,
@required TextDirection textDirection,
}) { }) {
final PageView child = new PageView( final PageView child = new PageView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -33,10 +35,13 @@ Widget buildFrame({ ...@@ -33,10 +35,13 @@ Widget buildFrame({
// The test framework forces the frame to be 800x600, so we need to create // The test framework forces the frame to be 800x600, so we need to create
// an outer container where we can change the size. // an outer container where we can change the size.
return new Center( return new Directionality(
textDirection: textDirection,
child: new Center(
child: new Container( child: new Container(
width: pageSize.width, height: pageSize.height, child: child, width: pageSize.width, height: pageSize.height, child: child,
), ),
),
); );
} }
...@@ -58,12 +63,15 @@ Future<Null> pageRight(WidgetTester tester) { ...@@ -58,12 +63,15 @@ Future<Null> pageRight(WidgetTester tester) {
void main() { void main() {
testWidgets('PageView default control', (WidgetTester tester) async { testWidgets('PageView default control', (WidgetTester tester) async {
await tester.pumpWidget(new Center(child: new PageView())); await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(child: new PageView())
));
}); });
testWidgets('PageView control test', (WidgetTester tester) async { testWidgets('PageView control test (LTR)', (WidgetTester tester) async {
currentPage = null; currentPage = null;
await tester.pumpWidget(buildFrame()); await tester.pumpWidget(buildFrame(textDirection: TextDirection.ltr));
expect(currentPage, isNull); expect(currentPage, isNull);
await pageLeft(tester); await pageLeft(tester);
expect(currentPage, equals(1)); expect(currentPage, equals(1));
...@@ -89,9 +97,9 @@ void main() { ...@@ -89,9 +97,9 @@ void main() {
expect(currentPage, equals(0)); expect(currentPage, equals(0));
}); });
testWidgets('PageView with reverse', (WidgetTester tester) async { testWidgets('PageView with reverse (LTR)', (WidgetTester tester) async {
currentPage = null; currentPage = null;
await tester.pumpWidget(buildFrame(reverse: true)); await tester.pumpWidget(buildFrame(reverse: true, textDirection: TextDirection.ltr));
await pageRight(tester); await pageRight(tester);
expect(currentPage, equals(1)); expect(currentPage, equals(1));
...@@ -122,4 +130,66 @@ void main() { ...@@ -122,4 +130,66 @@ void main() {
expect(find.text('4'), findsNothing); expect(find.text('4'), findsNothing);
expect(find.text('5'), findsNothing); expect(find.text('5'), findsNothing);
}); });
testWidgets('PageView control test (RTL)', (WidgetTester tester) async {
currentPage = null;
await tester.pumpWidget(buildFrame(textDirection: TextDirection.rtl));
await pageRight(tester);
expect(currentPage, equals(1));
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
expect(find.text('2'), findsNothing);
expect(find.text('3'), findsNothing);
expect(find.text('4'), findsNothing);
expect(find.text('5'), findsNothing);
await pageLeft(tester);
expect(currentPage, equals(0));
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
expect(find.text('2'), findsNothing);
expect(find.text('3'), findsNothing);
expect(find.text('4'), findsNothing);
expect(find.text('5'), findsNothing);
await pageLeft(tester);
expect(currentPage, equals(0));
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
expect(find.text('2'), findsNothing);
expect(find.text('3'), findsNothing);
expect(find.text('4'), findsNothing);
expect(find.text('5'), findsNothing);
});
testWidgets('PageView with reverse (RTL)', (WidgetTester tester) async {
currentPage = null;
await tester.pumpWidget(buildFrame(reverse: true, textDirection: TextDirection.rtl));
expect(currentPage, isNull);
await pageLeft(tester);
expect(currentPage, equals(1));
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
expect(find.text('2'), findsNothing);
expect(find.text('3'), findsNothing);
expect(find.text('4'), findsNothing);
expect(find.text('5'), findsNothing);
await pageRight(tester);
expect(currentPage, equals(0));
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
expect(find.text('2'), findsNothing);
expect(find.text('3'), findsNothing);
expect(find.text('4'), findsNothing);
expect(find.text('5'), findsNothing);
await pageRight(tester);
expect(currentPage, equals(0));
});
} }
...@@ -11,7 +11,9 @@ const List<int> items = const <int>[0, 1, 2, 3, 4, 5]; ...@@ -11,7 +11,9 @@ const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
void main() { void main() {
testWidgets('Tap item after scroll - horizontal', (WidgetTester tester) async { testWidgets('Tap item after scroll - horizontal', (WidgetTester tester) async {
final List<int> tapped = <int>[]; final List<int> tapped = <int>[];
await tester.pumpWidget(new Center( await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new Container( child: new Container(
height: 50.0, height: 50.0,
child: new ListView( child: new ListView(
...@@ -27,6 +29,7 @@ void main() { ...@@ -27,6 +29,7 @@ void main() {
}).toList(), }).toList(),
), ),
), ),
),
)); ));
await tester.drag(find.text('2'), const Offset(-280.0, 0.0)); await tester.drag(find.text('2'), const Offset(-280.0, 0.0));
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
......
...@@ -22,7 +22,9 @@ class TestItem extends StatelessWidget { ...@@ -22,7 +22,9 @@ class TestItem extends StatelessWidget {
} }
Widget buildFrame({ int count, double width, double height, Axis scrollDirection }) { Widget buildFrame({ int count, double width, double height, Axis scrollDirection }) {
return new CustomScrollView( return new Directionality(
textDirection: TextDirection.ltr,
child: new CustomScrollView(
scrollDirection: scrollDirection ?? Axis.vertical, scrollDirection: scrollDirection ?? Axis.vertical,
slivers: <Widget>[ slivers: <Widget>[
new SliverPrototypeExtentList( new SliverPrototypeExtentList(
...@@ -33,6 +35,7 @@ Widget buildFrame({ int count, double width, double height, Axis scrollDirection ...@@ -33,6 +35,7 @@ Widget buildFrame({ int count, double width, double height, Axis scrollDirection
), ),
), ),
], ],
),
); );
} }
......
...@@ -6,8 +6,8 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -6,8 +6,8 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
Future<Null> test(WidgetTester tester, double offset, EdgeInsets padding, AxisDirection axisDirection) { Future<Null> test(WidgetTester tester, double offset, EdgeInsetsGeometry padding, AxisDirection axisDirection, { TextDirection textDirection }) {
return tester.pumpWidget(new Viewport( Widget widget = new Viewport(
offset: new ViewportOffset.fixed(offset), offset: new ViewportOffset.fixed(offset),
axisDirection: axisDirection, axisDirection: axisDirection,
slivers: <Widget>[ slivers: <Widget>[
...@@ -18,7 +18,14 @@ Future<Null> test(WidgetTester tester, double offset, EdgeInsets padding, AxisDi ...@@ -18,7 +18,14 @@ Future<Null> test(WidgetTester tester, double offset, EdgeInsets padding, AxisDi
), ),
const SliverToBoxAdapter(child: const SizedBox(width: 400.0, height: 400.0, child: const Text('after'))), const SliverToBoxAdapter(child: const SizedBox(width: 400.0, height: 400.0, child: const Text('after'))),
], ],
)); );
if (textDirection != null) {
widget = new Directionality(
textDirection: textDirection,
child: widget,
);
}
return tester.pumpWidget(widget);
} }
void verify(WidgetTester tester, List<Rect> answerKey) { void verify(WidgetTester tester, List<Rect> answerKey) {
...@@ -33,7 +40,7 @@ void verify(WidgetTester tester, List<Rect> answerKey) { ...@@ -33,7 +40,7 @@ void verify(WidgetTester tester, List<Rect> answerKey) {
} }
void main() { void main() {
testWidgets('Viewport+SliverPadding basic test', (WidgetTester tester) async { testWidgets('Viewport+SliverPadding basic test (VISUAL)', (WidgetTester tester) async {
final EdgeInsets padding = const EdgeInsets.fromLTRB(25.0, 20.0, 15.0, 35.0); final EdgeInsets padding = const EdgeInsets.fromLTRB(25.0, 20.0, 15.0, 35.0);
await test(tester, 0.0, padding, AxisDirection.down); await test(tester, 0.0, padding, AxisDirection.down);
expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0))); expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0)));
...@@ -72,6 +79,84 @@ void main() { ...@@ -72,6 +79,84 @@ void main() {
]); ]);
}); });
testWidgets('Viewport+SliverPadding basic test (LTR)', (WidgetTester tester) async {
final EdgeInsetsDirectional padding = const EdgeInsetsDirectional.fromSTEB(25.0, 20.0, 15.0, 35.0);
await test(tester, 0.0, padding, AxisDirection.down, textDirection: TextDirection.ltr);
expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0)));
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, 0.0, 800.0, 400.0),
new Rect.fromLTWH(25.0, 420.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 600.0, 800.0, 400.0),
]);
await test(tester, 200.0, padding, AxisDirection.down, textDirection: TextDirection.ltr);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -200.0, 800.0, 400.0),
new Rect.fromLTWH(25.0, 220.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 600.0, 800.0, 400.0),
]);
await test(tester, 390.0, padding, AxisDirection.down, textDirection: TextDirection.ltr);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -390.0, 800.0, 400.0),
new Rect.fromLTWH(25.0, 30.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 465.0, 800.0, 400.0),
]);
await test(tester, 490.0, padding, AxisDirection.down, textDirection: TextDirection.ltr);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -490.0, 800.0, 400.0),
new Rect.fromLTWH(25.0, -70.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 365.0, 800.0, 400.0),
]);
await test(tester, 10000.0, padding, AxisDirection.down, textDirection: TextDirection.ltr);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -10000.0, 800.0, 400.0),
new Rect.fromLTWH(25.0, -9580.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, -9145.0, 800.0, 400.0),
]);
});
testWidgets('Viewport+SliverPadding basic test (RTL)', (WidgetTester tester) async {
final EdgeInsetsDirectional padding = const EdgeInsetsDirectional.fromSTEB(25.0, 20.0, 15.0, 35.0);
await test(tester, 0.0, padding, AxisDirection.down, textDirection: TextDirection.rtl);
expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0)));
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, 0.0, 800.0, 400.0),
new Rect.fromLTWH(15.0, 420.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 600.0, 800.0, 400.0),
]);
await test(tester, 200.0, padding, AxisDirection.down, textDirection: TextDirection.rtl);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -200.0, 800.0, 400.0),
new Rect.fromLTWH(15.0, 220.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 600.0, 800.0, 400.0),
]);
await test(tester, 390.0, padding, AxisDirection.down, textDirection: TextDirection.rtl);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -390.0, 800.0, 400.0),
new Rect.fromLTWH(15.0, 30.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 465.0, 800.0, 400.0),
]);
await test(tester, 490.0, padding, AxisDirection.down, textDirection: TextDirection.rtl);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -490.0, 800.0, 400.0),
new Rect.fromLTWH(15.0, -70.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, 365.0, 800.0, 400.0),
]);
await test(tester, 10000.0, padding, AxisDirection.down, textDirection: TextDirection.rtl);
verify(tester, <Rect>[
new Rect.fromLTWH(0.0, -10000.0, 800.0, 400.0),
new Rect.fromLTWH(15.0, -9580.0, 760.0, 400.0),
new Rect.fromLTWH(0.0, -9145.0, 800.0, 400.0),
]);
});
testWidgets('Viewport+SliverPadding hit testing', (WidgetTester tester) async { testWidgets('Viewport+SliverPadding hit testing', (WidgetTester tester) async {
final EdgeInsets padding = const EdgeInsets.all(30.0); final EdgeInsets padding = const EdgeInsets.all(30.0);
await test(tester, 350.0, padding, AxisDirection.down); await test(tester, 350.0, padding, AxisDirection.down);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment