Unverified Commit f3874359 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Add Spacer Widget (#16642)

This adds a simple spacer widget first suggested by Scott Stoll (@ScottS2017) in the abandoned PR #15802

This PR replaces that one, cleans it up, and adds a test.
parent ebd9a962
......@@ -3233,6 +3233,7 @@ class PositionedDirectional extends StatelessWidget {
/// * [Column], for a version of this widget that is always vertical.
/// * [Expanded], to indicate children that should take all the remaining room.
/// * [Flexible], to indicate children that should share the remaining room but
/// * [Spacer], a widget that takes up space proportional to it's flex value.
/// that may be sized smaller (leaving some remaining room unused).
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class Flex extends MultiChildRenderObjectWidget {
......@@ -3565,6 +3566,7 @@ class Flex extends MultiChildRenderObjectWidget {
/// * [Expanded], to indicate children that should take all the remaining room.
/// * [Flexible], to indicate children that should share the remaining room but
/// that may by sized smaller (leaving some remaining room unused).
/// * [Spacer], a widget that takes up space proportional to it's flex value.
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class Row extends Flex {
/// Creates a horizontal array of children.
......@@ -3759,6 +3761,7 @@ class Row extends Flex {
/// that may size smaller (leaving some remaining room unused).
/// * [SingleChildScrollView], whose documentation discusses some ways to
/// use a [Column] inside a scrolling container.
/// * [Spacer], a widget that takes up space proportional to it's flex value.
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class Column extends Flex {
/// Creates a vertical array of children.
......@@ -3810,6 +3813,7 @@ class Column extends Flex {
/// See also:
///
/// * [Expanded], which forces the child to expand to fill the available space.
/// * [Spacer], a widget that takes up space proportional to it's flex value.
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class Flexible extends ParentDataWidget<Flex> {
/// Creates a widget that controls how a child of a [Row], [Column], or [Flex]
......@@ -3883,6 +3887,7 @@ class Flexible extends ParentDataWidget<Flex> {
/// See also:
///
/// * [Flexible], which does not force the child to fill the available space.
/// * [Spacer], a widget that takes up space proportional to it's flex value.
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class Expanded extends Flexible {
/// Creates a widget that expands a child of a [Row], [Column], or [Flex]
......
// Copyright 2018 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/rendering.dart';
import 'basic.dart';
import 'framework.dart';
/// Spacer creates an adjustable, empty spacer that can be used to tune the
/// spacing between widgets in a [Flex] container, like [Row] or [Column].
///
/// The [Spacer] widget will take up any available space, so setting the
/// [Flex.mainAxisAlignment] on a flex container that contains a [Spacer] to
/// [MainAxisAlignment.spaceAround], [MainAxisAlignment.spaceBetween], or
/// [MainAxisAlignment.spaceEvenly] will not have any visible effect: the
/// [Spacer] has taken up all of the additional space, so there is none left to
/// redistribute.
///
/// ## Sample code
///
/// ```dart
/// new Row(
/// children: <Widget>[
/// new Text('Begin'),
/// new Spacer(), // Defaults to a flex of one.
/// new Text('Middle'),
/// // Gives twice the space between Middle and End than Begin and Middle.
/// new Spacer(flex: 2),
/// new Text('End'),
/// ],
/// )
/// ```
///
/// See also:
///
/// * [Row] and [Column], which are the most common containers to use a Spacer
/// in.
/// * [SizedBox], to create a box with a specific size and an optional child.
class Spacer extends StatelessWidget {
/// Creates a flexible space to insert into a [Flexible] widget.
///
/// The [flex] parameter may not be null or less than one.
const Spacer({Key key, this.flex: 1})
: assert(flex != null),
assert(flex > 0),
super(key: key);
/// The flex factor to use in determining how much space to take up.
///
/// The amount of space the [Spacer] can occupy in the main axis is determined
/// by dividing the free space proportionately, after placing the inflexible
/// children, according to the flex factors of the flexible children.
///
/// Defaults to one.
final int flex;
@override
Widget build(BuildContext context) {
return new Expanded(
flex: flex,
child: new ConstrainedBox(
constraints: const BoxConstraints.expand(),
),
);
}
}
\ No newline at end of file
......@@ -86,6 +86,7 @@ export 'src/widgets/size_changed_layout_notifier.dart';
export 'src/widgets/sliver.dart';
export 'src/widgets/sliver_persistent_header.dart';
export 'src/widgets/sliver_prototype_extent_list.dart';
export 'src/widgets/spacer.dart';
export 'src/widgets/status_transitions.dart';
export 'src/widgets/table.dart';
export 'src/widgets/text.dart';
......
// Copyright 2018 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';
void main() {
testWidgets('Spacer takes up space.', (WidgetTester tester) async {
await tester.pumpWidget(new Column(
children: const <Widget>[
const SizedBox(width: 10.0, height: 10.0),
const Spacer(),
const SizedBox(width: 10.0, height: 10.0),
],
));
final Rect spacerRect = tester.getRect(find.byType(Spacer));
expect(spacerRect.size, const Size(800.0, 580.0));
expect(spacerRect.topLeft, const Offset(0.0, 10.0));
});
testWidgets('Spacer takes up space proportional to flex.', (WidgetTester tester) async {
const Spacer spacer1 = const Spacer();
const Spacer spacer2 = const Spacer(flex: 1);
const Spacer spacer3 = const Spacer(flex: 2);
const Spacer spacer4 = const Spacer(flex: 4);
await tester.pumpWidget(new Row(
textDirection: TextDirection.rtl,
children: const <Widget>[
const SizedBox(width: 10.0, height: 10.0),
spacer1,
const SizedBox(width: 10.0, height: 10.0),
spacer2,
const SizedBox(width: 10.0, height: 10.0),
spacer3,
const SizedBox(width: 10.0, height: 10.0),
spacer4,
const SizedBox(width: 10.0, height: 10.0),
],
));
final Rect spacer1Rect = tester.getRect(find.byType(Spacer).at(0));
final Rect spacer2Rect = tester.getRect(find.byType(Spacer).at(1));
final Rect spacer3Rect = tester.getRect(find.byType(Spacer).at(2));
final Rect spacer4Rect = tester.getRect(find.byType(Spacer).at(3));
expect(spacer1Rect.size.height, 600.0);
expect(spacer1Rect.size.width, closeTo(93.8, 0.1));
expect(spacer1Rect.left, closeTo(696.3, 0.1));
expect(spacer2Rect.size.width, closeTo(93.8, 0.1));
expect(spacer2Rect.left, closeTo(592.5, 0.1));
expect(spacer3Rect.size.width, spacer2Rect.size.width * 2.0);
expect(spacer3Rect.left, closeTo(395.0, 0.1));
expect(spacer4Rect.size.width, spacer3Rect.size.width * 2.0);
expect(spacer4Rect.left, closeTo(10.0, 0.1));
});
}
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