| 1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | /// @docImport 'package:flutter/material.dart'; |
| 6 | library; |
| 7 | |
| 8 | import 'package:flutter/rendering.dart'; |
| 9 | |
| 10 | import 'basic.dart'; |
| 11 | import 'framework.dart'; |
| 12 | |
| 13 | /// An interface for widgets that can return the size this widget would prefer |
| 14 | /// if it were otherwise unconstrained. |
| 15 | /// |
| 16 | /// There are a few cases, notably [AppBar] and [TabBar], where it would be |
| 17 | /// undesirable for the widget to constrain its own size but where the widget |
| 18 | /// needs to expose a preferred or "default" size. For example a primary |
| 19 | /// [Scaffold] sets its app bar height to the app bar's preferred height |
| 20 | /// plus the height of the system status bar. |
| 21 | /// |
| 22 | /// Widgets that need to know the preferred size of their child can require |
| 23 | /// that their child implement this interface by using this class rather |
| 24 | /// than [Widget] as the type of their `child` property. |
| 25 | /// |
| 26 | /// Use [PreferredSize] to give a preferred size to an arbitrary widget. |
| 27 | abstract class PreferredSizeWidget implements Widget { |
| 28 | /// The size this widget would prefer if it were otherwise unconstrained. |
| 29 | /// |
| 30 | /// In many cases it's only necessary to define one preferred dimension. |
| 31 | /// For example the [Scaffold] only depends on its app bar's preferred |
| 32 | /// height. In that case implementations of this method can just return |
| 33 | /// `Size.fromHeight(myAppBarHeight)`. |
| 34 | Size get preferredSize; |
| 35 | } |
| 36 | |
| 37 | /// A widget with a preferred size. |
| 38 | /// |
| 39 | /// This widget does not impose any constraints on its child, and it doesn't |
| 40 | /// affect the child's layout in any way. It just advertises a preferred size |
| 41 | /// which can be used by the parent. |
| 42 | /// |
| 43 | /// Parents like [Scaffold] use [PreferredSizeWidget] to require that their |
| 44 | /// children implement that interface. To give a preferred size to an arbitrary |
| 45 | /// widget so that it can be used in a `child` property of that type, this |
| 46 | /// widget, [PreferredSize], can be used. |
| 47 | /// |
| 48 | /// Widgets like [AppBar] implement a [PreferredSizeWidget], so that this |
| 49 | /// [PreferredSize] widget is not necessary for them. |
| 50 | /// |
| 51 | /// {@tool dartpad} |
| 52 | /// This sample shows a custom widget, similar to an [AppBar], which uses a |
| 53 | /// [PreferredSize] widget, with its height set to 80 logical pixels. |
| 54 | /// Changing the [PreferredSize] can be used to change the height |
| 55 | /// of the custom app bar. |
| 56 | /// |
| 57 | /// ** See code in examples/api/lib/widgets/preferred_size/preferred_size.0.dart ** |
| 58 | /// {@end-tool} |
| 59 | /// |
| 60 | /// See also: |
| 61 | /// |
| 62 | /// * [AppBar.bottom] and [Scaffold.appBar], which require preferred size widgets. |
| 63 | /// * [PreferredSizeWidget], the interface which this widget implements to expose |
| 64 | /// its preferred size. |
| 65 | /// * [AppBar] and [TabBar], which implement PreferredSizeWidget. |
| 66 | class PreferredSize extends StatelessWidget implements PreferredSizeWidget { |
| 67 | /// Creates a widget that has a preferred size that the parent can query. |
| 68 | const PreferredSize({super.key, required this.preferredSize, required this.child}); |
| 69 | |
| 70 | /// The widget below this widget in the tree. |
| 71 | /// |
| 72 | /// {@macro flutter.widgets.ProxyWidget.child} |
| 73 | final Widget child; |
| 74 | |
| 75 | @override |
| 76 | final Size preferredSize; |
| 77 | |
| 78 | @override |
| 79 | Widget build(BuildContext context) => child; |
| 80 | } |
| 81 | |