From 6ff02dbc83bea984c8f84cd269030d75c8f8ba25 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 11 Oct 2023 19:39:56 +0200 Subject: [PATCH] Include size factors when computing the intrinsic size of a `RenderPositionedBox` (#135823) This PR includes the `widthFactor` and `heightFactor` when computing the intrinsic size of a `RenderPositionedBox`.
Code sample Red should have a height of 100, blue one of 200. ```dart import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Intrinsic Bug', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: Scaffold( body: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: IntrinsicHeight( child: Align( heightFactor: 0.5, child: Container( height: 200, color: Colors.red, ), ), ), ), Expanded( child: Container( height: 200, color: Colors.blue, ), ), ], ), ), ); } } ```
Before: ![grafik](https://github.com/flutter/flutter/assets/45403027/447d8b9b-e7f3-482a-900d-53e436830321) After: ![grafik](https://github.com/flutter/flutter/assets/45403027/6d1a104b-3327-47e2-8b36-798ed0136793) Fix #135822 --- .../lib/src/rendering/shifted_box.dart | 20 +++++++++++++++++++ .../test/rendering/positioned_box_test.dart | 12 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/packages/flutter/lib/src/rendering/shifted_box.dart b/packages/flutter/lib/src/rendering/shifted_box.dart index 2afe15c064..85de3a16cd 100644 --- a/packages/flutter/lib/src/rendering/shifted_box.dart +++ b/packages/flutter/lib/src/rendering/shifted_box.dart @@ -407,6 +407,26 @@ class RenderPositionedBox extends RenderAligningShiftedBox { markNeedsLayout(); } + @override + double computeMinIntrinsicWidth(double height) { + return super.computeMinIntrinsicWidth(height) * (_widthFactor ?? 1); + } + + @override + double computeMaxIntrinsicWidth(double height) { + return super.computeMaxIntrinsicWidth(height) * (_widthFactor ?? 1); + } + + @override + double computeMinIntrinsicHeight(double width) { + return super.computeMinIntrinsicHeight(width) * (_heightFactor ?? 1); + } + + @override + double computeMaxIntrinsicHeight(double width) { + return super.computeMaxIntrinsicHeight(width) * (_heightFactor ?? 1); + } + @override Size computeDryLayout(BoxConstraints constraints) { final bool shrinkWrapWidth = _widthFactor != null || constraints.maxWidth == double.infinity; diff --git a/packages/flutter/test/rendering/positioned_box_test.dart b/packages/flutter/test/rendering/positioned_box_test.dart index f41613bdc4..e47709c2e8 100644 --- a/packages/flutter/test/rendering/positioned_box_test.dart +++ b/packages/flutter/test/rendering/positioned_box_test.dart @@ -55,6 +55,10 @@ void main() { final RenderPositionedBox positioner = RenderPositionedBox(child: sizer, widthFactor: 1.0, heightFactor: 0.0); layout(positioner, constraints: BoxConstraints.loose(const Size(200.0, 200.0))); + expect(positioner.computeMinIntrinsicWidth(200), equals(100.0)); + expect(positioner.computeMaxIntrinsicWidth(200), equals(100.0)); + expect(positioner.computeMinIntrinsicHeight(200), equals(0)); + expect(positioner.computeMaxIntrinsicHeight(200), equals(0)); expect(positioner.size.width, equals(100.0)); expect(positioner.size.height, equals(0.0)); @@ -62,6 +66,10 @@ void main() { positioner.heightFactor = 0.5; pumpFrame(); + expect(positioner.computeMinIntrinsicWidth(200), equals(50.0)); + expect(positioner.computeMaxIntrinsicWidth(200), equals(50.0)); + expect(positioner.computeMinIntrinsicHeight(200), equals(50.0)); + expect(positioner.computeMaxIntrinsicHeight(200), equals(50.0)); expect(positioner.size.width, equals(50.0)); expect(positioner.size.height, equals(50.0)); @@ -69,6 +77,10 @@ void main() { positioner.heightFactor = null; pumpFrame(); + expect(positioner.computeMinIntrinsicWidth(200), equals(100.0)); + expect(positioner.computeMaxIntrinsicWidth(200), equals(100.0)); + expect(positioner.computeMinIntrinsicHeight(200), equals(100.0)); + expect(positioner.computeMaxIntrinsicHeight(200), equals(100.0)); expect(positioner.size.width, equals(200.0)); expect(positioner.size.height, equals(200.0)); });