diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index ac5d883bd4..39f45ae468 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -541,16 +541,26 @@ class RenderAspectRatio extends RenderProxyBox { /// depth of the tree. class RenderIntrinsicWidth extends RenderProxyBox { /// Creates a render object that sizes itself to its child's intrinsic width. + /// + /// If [stepWidth] is non-null it must be > 0.0. Similarly If [stepHeight] is + /// non-null it must be > 0.0. RenderIntrinsicWidth({ double stepWidth, double stepHeight, RenderBox child - }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); + }) : assert(stepWidth == null || stepWidth > 0.0), + assert(stepHeight == null || stepHeight > 0.0), + _stepWidth = stepWidth, + _stepHeight = stepHeight, + super(child); /// If non-null, force the child's width to be a multiple of this value. + /// + /// This value must be null or > 0.0. double get stepWidth => _stepWidth; double _stepWidth; set stepWidth(double value) { + assert(value == null || value > 0.0); if (value == _stepWidth) return; _stepWidth = value; @@ -558,9 +568,12 @@ class RenderIntrinsicWidth extends RenderProxyBox { } /// If non-null, force the child's height to be a multiple of this value. + /// + /// This value must be null or > 0.0. double get stepHeight => _stepHeight; double _stepHeight; set stepHeight(double value) { + assert(value == null || value > 0.0); if (value == _stepHeight) return; _stepHeight = value; diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index 4475fa8177..5b5a88f448 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -2477,24 +2477,43 @@ class IntrinsicWidth extends SingleChildRenderObjectWidget { /// /// This class is relatively expensive. Avoid using it where possible. const IntrinsicWidth({ Key key, this.stepWidth, this.stepHeight, Widget child }) - : super(key: key, child: child); + : assert(stepWidth == null || stepWidth >= 0.0), + assert(stepHeight == null || stepHeight >= 0.0), + super(key: key, child: child); /// If non-null, force the child's width to be a multiple of this value. + /// + /// If null or 0.0 the child's width will be the same as its maximum + /// intrinsic width. + /// + /// This value must not be negative. + /// + /// See also: + /// + /// * [RenderBox.getMaxIntrinsicWidth], which defines a widget's max + /// intrinsic width in general. final double stepWidth; /// If non-null, force the child's height to be a multiple of this value. + /// + /// If null or 0.0 the child's height will not be constrained. + /// + /// This value must not be negative. final double stepHeight; + double get _stepWidth => stepWidth == 0.0 ? null : stepWidth; + double get _stepHeight => stepHeight == 0.0 ? null : stepHeight; + @override RenderIntrinsicWidth createRenderObject(BuildContext context) { - return RenderIntrinsicWidth(stepWidth: stepWidth, stepHeight: stepHeight); + return RenderIntrinsicWidth(stepWidth: _stepWidth, stepHeight: _stepHeight); } @override void updateRenderObject(BuildContext context, RenderIntrinsicWidth renderObject) { renderObject - ..stepWidth = stepWidth - ..stepHeight = stepHeight; + ..stepWidth = _stepWidth + ..stepHeight = _stepHeight; } } diff --git a/packages/flutter/test/widgets/intrinsic_width_test.dart b/packages/flutter/test/widgets/intrinsic_width_test.dart new file mode 100644 index 0000000000..11bc398c91 --- /dev/null +++ b/packages/flutter/test/widgets/intrinsic_width_test.dart @@ -0,0 +1,30 @@ +// 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('Intrinsic stepWidth, stepHeight', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/25224 + Widget buildFrame(double stepWidth, double stepHeight) { + return Center( + child: IntrinsicWidth( + stepWidth: stepWidth, + stepHeight: stepHeight, + child: const SizedBox(width: 100.0, height: 50.0), + ), + ); + } + + await tester.pumpWidget(buildFrame(null, null)); + expect(tester.getSize(find.byType(IntrinsicWidth)), const Size(100.0, 50.0)); + + await tester.pumpWidget(buildFrame(0.0, 0.0)); + expect(tester.getSize(find.byType(IntrinsicWidth)), const Size(100.0, 50.0)); + + expect(() { buildFrame(-1.0, 0.0); }, throwsAssertionError); + expect(() { buildFrame(0.0, -1.0); }, throwsAssertionError); + }); +}