mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
parent
f9ae22677a
commit
ebe6da5b17
@ -170,7 +170,7 @@ class FancyImageItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new BlockBody(
|
||||
return new ListBody(
|
||||
children: <Widget>[
|
||||
new UserHeader('Ali Connors $index'),
|
||||
new ItemDescription(),
|
||||
@ -193,7 +193,7 @@ class FancyGalleryItem extends StatelessWidget {
|
||||
final int index;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new BlockBody(
|
||||
return new ListBody(
|
||||
children: <Widget>[
|
||||
new UserHeader('Ali Connors'),
|
||||
new ItemGalleryBox(index),
|
||||
|
@ -266,7 +266,7 @@ class AboutDialog extends StatelessWidget {
|
||||
body.add(new Expanded(
|
||||
child: new Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||
child: new BlockBody(
|
||||
child: new ListBody(
|
||||
children: <Widget>[
|
||||
new Text(name, style: Theme.of(context).textTheme.headline),
|
||||
new Text(version, style: Theme.of(context).textTheme.body1),
|
||||
@ -286,7 +286,7 @@ class AboutDialog extends StatelessWidget {
|
||||
body.addAll(children);
|
||||
return new AlertDialog(
|
||||
content: new SingleChildScrollView(
|
||||
child: new BlockBody(children: body),
|
||||
child: new ListBody(children: body),
|
||||
),
|
||||
actions: <Widget>[
|
||||
new FlatButton(
|
||||
|
@ -293,7 +293,7 @@ class SimpleDialog extends StatelessWidget {
|
||||
body.add(new Flexible(
|
||||
child: new SingleChildScrollView(
|
||||
padding: contentPadding ?? const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),
|
||||
child: new BlockBody(children: children),
|
||||
child: new ListBody(children: children),
|
||||
)
|
||||
));
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class ExpansionPanelList extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// The children of the expansion panel list. They are layed in a similar
|
||||
/// fashion to [BlockBody].
|
||||
/// fashion to [ListBody].
|
||||
final List<ExpansionPanel> children;
|
||||
|
||||
/// The callback that gets called whenever one of the expand/collapse buttons
|
||||
|
@ -74,7 +74,7 @@ class MaterialGap extends MergeableMaterialItem {
|
||||
/// Displays a list of [MergeableMaterialItem] children. The list contains
|
||||
/// [MaterialSlice] items whose boundaries are either "merged" with adjacent
|
||||
/// items or separated by a [MaterialGap]. The [children] are distributed along
|
||||
/// the given [mainAxis] in the same way as the children of a [BlockBody]. When
|
||||
/// the given [mainAxis] in the same way as the children of a [ListBody]. When
|
||||
/// the list of children changes, gaps are automatically animated open or closed
|
||||
/// as needed.
|
||||
///
|
||||
@ -522,7 +522,7 @@ class _MergeableMaterialState extends State<MergeableMaterial> with TickerProvid
|
||||
borderRadius: _borderRadius(i - 1, widgets.isEmpty, false),
|
||||
shape: BoxShape.rectangle
|
||||
),
|
||||
child: new BlockBody(
|
||||
child: new ListBody(
|
||||
mainAxis: config.mainAxis,
|
||||
children: slices
|
||||
)
|
||||
@ -593,7 +593,7 @@ class _MergeableMaterialState extends State<MergeableMaterial> with TickerProvid
|
||||
borderRadius: _borderRadius(i - 1, widgets.isEmpty, true),
|
||||
shape: BoxShape.rectangle
|
||||
),
|
||||
child: new BlockBody(
|
||||
child: new ListBody(
|
||||
mainAxis: config.mainAxis,
|
||||
children: slices
|
||||
)
|
||||
@ -602,7 +602,7 @@ class _MergeableMaterialState extends State<MergeableMaterial> with TickerProvid
|
||||
slices = <Widget>[];
|
||||
}
|
||||
|
||||
return new _MergeableMaterialBlockBody(
|
||||
return new _MergeableMaterialListBody(
|
||||
mainAxis: config.mainAxis,
|
||||
boxShadows: kElevationToShadow[config.elevation],
|
||||
items: _children,
|
||||
@ -635,8 +635,8 @@ class _MergeableMaterialSliceKey extends GlobalKey {
|
||||
}
|
||||
}
|
||||
|
||||
class _MergeableMaterialBlockBody extends BlockBody {
|
||||
_MergeableMaterialBlockBody({
|
||||
class _MergeableMaterialListBody extends ListBody {
|
||||
_MergeableMaterialListBody({
|
||||
List<Widget> children,
|
||||
Axis mainAxis: Axis.vertical,
|
||||
this.items,
|
||||
@ -647,24 +647,24 @@ class _MergeableMaterialBlockBody extends BlockBody {
|
||||
List<BoxShadow> boxShadows;
|
||||
|
||||
@override
|
||||
RenderBlock createRenderObject(BuildContext context) {
|
||||
return new _MergeableMaterialRenderBlock(
|
||||
RenderListBody createRenderObject(BuildContext context) {
|
||||
return new _RenderMergeableMaterialListBody(
|
||||
mainAxis: mainAxis,
|
||||
boxShadows: boxShadows
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderBlock renderObject) {
|
||||
final _MergeableMaterialRenderBlock materialRenderBlock = renderObject;
|
||||
materialRenderBlock
|
||||
void updateRenderObject(BuildContext context, RenderListBody renderObject) {
|
||||
final _RenderMergeableMaterialListBody materialRenderListBody = renderObject;
|
||||
materialRenderListBody
|
||||
..mainAxis = mainAxis
|
||||
..boxShadows = boxShadows;
|
||||
}
|
||||
}
|
||||
|
||||
class _MergeableMaterialRenderBlock extends RenderBlock {
|
||||
_MergeableMaterialRenderBlock({
|
||||
class _RenderMergeableMaterialListBody extends RenderListBody {
|
||||
_RenderMergeableMaterialListBody({
|
||||
List<RenderBox> children,
|
||||
Axis mainAxis: Axis.vertical,
|
||||
this.boxShadows
|
||||
@ -692,7 +692,7 @@ class _MergeableMaterialRenderBlock extends RenderBlock {
|
||||
int i = 0;
|
||||
|
||||
while (child != null) {
|
||||
final BlockParentData childParentData = child.parentData;
|
||||
final ListBodyParentData childParentData = child.parentData;
|
||||
final Rect rect = (childParentData.offset + offset) & child.size;
|
||||
if (i % 2 == 0)
|
||||
_paintShadows(context.canvas, rect);
|
||||
|
@ -300,7 +300,7 @@ class _PopupMenu<T> extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: _kMenuVerticalPadding
|
||||
),
|
||||
child: new BlockBody(children: children),
|
||||
child: new ListBody(children: children),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -7,37 +7,39 @@ import 'dart:math' as math;
|
||||
import 'box.dart';
|
||||
import 'object.dart';
|
||||
|
||||
/// Parent data for use with [RenderBlockBase].
|
||||
class BlockParentData extends ContainerBoxParentDataMixin<RenderBox> { }
|
||||
/// Parent data for use with [RenderListBody].
|
||||
class ListBodyParentData extends ContainerBoxParentDataMixin<RenderBox> { }
|
||||
|
||||
typedef double _ChildSizingFunction(RenderBox child);
|
||||
|
||||
/// Implements the block layout algorithm.
|
||||
/// Displays its children sequentially along a given axis, forcing them to the
|
||||
/// dimensions of the parent in the other axis.
|
||||
///
|
||||
/// In block layout, children are arranged linearly along the main axis (either
|
||||
/// horizontally or vertically). In the cross axis, children are stretched to
|
||||
/// match the block's cross-axis extent. In the main axis, children are given
|
||||
/// unlimited space and the block expands its main axis to contain all its
|
||||
/// children. Because blocks expand in the main axis, blocks must be given
|
||||
/// unlimited space in the main axis, typically by being contained in a
|
||||
/// viewport with a scrolling direction that matches the block's main axis.
|
||||
class RenderBlock extends RenderBox
|
||||
with ContainerRenderObjectMixin<RenderBox, BlockParentData>,
|
||||
RenderBoxContainerDefaultsMixin<RenderBox, BlockParentData> {
|
||||
/// Creates a block render object.
|
||||
/// This layout algorithm arranges its children linearly along the main axis
|
||||
/// (either horizontally or vertically). In the cross axis, children are
|
||||
/// stretched to match the box's cross-axis extent. In the main axis, children
|
||||
/// are given unlimited space and the box expands its main axis to contain all
|
||||
/// its children. Because [RenderListBody] boxes expand in the main axis, they
|
||||
/// must be given unlimited space in the main axis, typically by being contained
|
||||
/// in a viewport with a scrolling direction that matches the box's main axis.
|
||||
class RenderListBody extends RenderBox
|
||||
with ContainerRenderObjectMixin<RenderBox, ListBodyParentData>,
|
||||
RenderBoxContainerDefaultsMixin<RenderBox, ListBodyParentData> {
|
||||
/// Creates a render object that arranges its children sequentially along a
|
||||
/// given axis.
|
||||
///
|
||||
/// By default, the block positions children along the vertical axis.
|
||||
RenderBlock({
|
||||
/// By default, children are arranged along the vertical axis.
|
||||
RenderListBody({
|
||||
List<RenderBox> children,
|
||||
Axis mainAxis: Axis.vertical
|
||||
Axis mainAxis: Axis.vertical,
|
||||
}) : _mainAxis = mainAxis {
|
||||
addAll(children);
|
||||
}
|
||||
|
||||
@override
|
||||
void setupParentData(RenderBox child) {
|
||||
if (child.parentData is! BlockParentData)
|
||||
child.parentData = new BlockParentData();
|
||||
if (child.parentData is! ListBodyParentData)
|
||||
child.parentData = new ListBodyParentData();
|
||||
}
|
||||
|
||||
/// The direction to use as the main axis.
|
||||
@ -90,10 +92,10 @@ class RenderBlock extends RenderBox
|
||||
break;
|
||||
}
|
||||
throw new FlutterError(
|
||||
'RenderBlock must have unlimited space along its main axis.\n'
|
||||
'RenderBlock does not clip or resize its children, so it must be '
|
||||
'placed in a parent that does not constrain the block\'s main '
|
||||
'axis. You probably want to put the RenderBlock inside a '
|
||||
'RenderListBody must have unlimited space along its main axis.\n'
|
||||
'RenderListBody does not clip or resize its children, so it must be '
|
||||
'placed in a parent that does not constrain the main '
|
||||
'axis. You probably want to put the RenderListBody inside a '
|
||||
'RenderViewport with a matching main axis.'
|
||||
);
|
||||
});
|
||||
@ -112,11 +114,11 @@ class RenderBlock extends RenderBox
|
||||
// more specific to the exact situation in that case, and don't mention
|
||||
// nesting blocks in the negative case.
|
||||
throw new FlutterError(
|
||||
'RenderBlock must have a bounded constraint for its cross axis.\n'
|
||||
'RenderBlock forces its children to expand to fit the block\'s container, '
|
||||
'so it must be placed in a parent that does constrain the block\'s cross '
|
||||
'axis to a finite dimension. If you are attempting to nest a block with '
|
||||
'one direction inside a block of another direction, you will want to '
|
||||
'RenderListBody must have a bounded constraint for its cross axis.\n'
|
||||
'RenderListBody forces its children to expand to fit the RenderListBody\'s container, '
|
||||
'so it must be placed in a parent that constrains the cross '
|
||||
'axis to a finite dimension. If you are attempting to nest a RenderListBody with '
|
||||
'one direction inside one of another direction, you will want to '
|
||||
'wrap the inner one inside a box that fixes the dimension in that direction, '
|
||||
'for example, a RenderIntrinsicWidth or RenderIntrinsicHeight object. '
|
||||
'This is relatively expensive, however.' // (that's why we don't do it automatically)
|
||||
@ -127,7 +129,7 @@ class RenderBlock extends RenderBox
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
child.layout(innerConstraints, parentUsesSize: true);
|
||||
final BlockParentData childParentData = child.parentData;
|
||||
final ListBodyParentData childParentData = child.parentData;
|
||||
switch (mainAxis) {
|
||||
case Axis.horizontal:
|
||||
childParentData.offset = new Offset(position, 0.0);
|
||||
@ -164,7 +166,7 @@ class RenderBlock extends RenderBox
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
extent = math.max(extent, childSize(child));
|
||||
final BlockParentData childParentData = child.parentData;
|
||||
final ListBodyParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
return extent;
|
||||
@ -175,7 +177,7 @@ class RenderBlock extends RenderBox
|
||||
RenderBox child = firstChild;
|
||||
while (child != null) {
|
||||
extent += childSize(child);
|
||||
final BlockParentData childParentData = child.parentData;
|
||||
final ListBodyParentData childParentData = child.parentData;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
return extent;
|
||||
|
@ -1539,19 +1539,30 @@ class SliverPadding extends SingleChildRenderObjectWidget {
|
||||
|
||||
// LAYOUT NODES
|
||||
|
||||
/// A widget that uses the block layout algorithm for its children.
|
||||
/// A widget that arranges its children sequentially along a given axis, forcing
|
||||
/// them to the dimension of the parent in the other axis.
|
||||
///
|
||||
/// This widget is rarely used directly. Instead, consider using [SliverList],
|
||||
/// This widget is rarely used directly. Instead, consider using [ListView],
|
||||
/// which combines a similar layout algorithm with scrolling behavior, or
|
||||
/// [Column], which gives you more flexible control over the layout of a
|
||||
/// vertical set of boxes.
|
||||
///
|
||||
/// For details about the block layout algorithm, see [RenderBlockBase].
|
||||
class BlockBody extends MultiChildRenderObjectWidget {
|
||||
/// Creates a block layout widget.
|
||||
/// See also:
|
||||
///
|
||||
/// * [RenderListBody], which implements this layout algorithm and the
|
||||
/// documentation for which describes some of its subtleties.
|
||||
/// * [SingleChildScrollView], which is sometimes used with [ListBody] to
|
||||
/// make the contents scrollable.
|
||||
/// * [Column] and [Row], which implement a more elaborate version of
|
||||
/// this layout algorithm (at the cost of being slightly less efficient).
|
||||
/// * [ListView], which implements an efficient scrolling version of this
|
||||
/// layout algorithm.
|
||||
class ListBody extends MultiChildRenderObjectWidget {
|
||||
/// Creates a layout widget that arranges its children sequentially along a
|
||||
/// given axis.
|
||||
///
|
||||
/// By default, the [mainAxis] is [Axis.vertical].
|
||||
BlockBody({
|
||||
ListBody({
|
||||
Key key,
|
||||
this.mainAxis: Axis.vertical,
|
||||
List<Widget> children: const <Widget>[],
|
||||
@ -1562,10 +1573,10 @@ class BlockBody extends MultiChildRenderObjectWidget {
|
||||
final Axis mainAxis;
|
||||
|
||||
@override
|
||||
RenderBlock createRenderObject(BuildContext context) => new RenderBlock(mainAxis: mainAxis);
|
||||
RenderListBody createRenderObject(BuildContext context) => new RenderListBody(mainAxis: mainAxis);
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderBlock renderObject) {
|
||||
void updateRenderObject(BuildContext context, RenderListBody renderObject) {
|
||||
renderObject.mainAxis = mainAxis;
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ import 'scrollable.dart';
|
||||
/// It is also useful if you need to shrink-wrap in both axes (the main
|
||||
/// scrolling direction as well as the cross axis), as one might see in a dialog
|
||||
/// or pop-up menu. In that case, you might pair the [SingleChildScrollView]
|
||||
/// with a [BlockBody] child.
|
||||
/// with a [ListBody] child.
|
||||
///
|
||||
/// When you have a list of children and do not require cross-axis
|
||||
/// shrink-wrapping behavior, for example a scrolling list that is always the
|
||||
/// width of the screen, consider [ListView], which is vastly more efficient
|
||||
/// that a [SingleChildScrollView] containing a [BlockBody] or [Column] with
|
||||
/// that a [SingleChildScrollView] containing a [ListBody] or [Column] with
|
||||
/// many children.
|
||||
///
|
||||
/// See also:
|
||||
|
@ -6,14 +6,14 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('block and paragraph intrinsics', () {
|
||||
test('list body and paragraph intrinsics', () {
|
||||
final RenderParagraph paragraph = new RenderParagraph(
|
||||
const TextSpan(
|
||||
style: const TextStyle(height: 1.0),
|
||||
text: 'Hello World'
|
||||
)
|
||||
);
|
||||
final RenderBlock testBlock = new RenderBlock(
|
||||
final RenderListBody testBlock = new RenderListBody(
|
||||
children: <RenderBox>[
|
||||
paragraph,
|
||||
]
|
||||
|
@ -18,7 +18,7 @@ Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse: false })
|
||||
child: new SingleChildScrollView(
|
||||
scrollDirection: scrollDirection,
|
||||
reverse: reverse,
|
||||
child: new BlockBody(
|
||||
child: new ListBody(
|
||||
mainAxis: scrollDirection,
|
||||
children: <Widget>[
|
||||
new Container(key: const ValueKey<int>(0), width: 200.0, height: 200.0),
|
||||
@ -178,7 +178,7 @@ void main() {
|
||||
width: 600.0,
|
||||
height: 400.0,
|
||||
child: new SingleChildScrollView(
|
||||
child: new BlockBody(
|
||||
child: new ListBody(
|
||||
children: <Widget>[
|
||||
new Container(height: 200.0),
|
||||
new Container(height: 200.0),
|
||||
|
Loading…
Reference in New Issue
Block a user