preferred_size.dart 3.45 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// 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';

/// An interface for widgets that can return the size this widget would prefer
/// if it were otherwise unconstrained.
///
/// There are a few cases, notably [AppBar] and [TabBar], where it would be
/// undesirable for the widget to constrain its own size but where the widget
/// needs to expose a preferred or "default" size. For example a primary
/// [Scaffold] sets its app bar height to the app bar's preferred height
/// plus the height of the system status bar.
///
19 20 21 22
/// Widgets that need to know the preferred size of their child can require
/// that their child implement this interface by using this class rather
/// than [Widget] as the type of their `child` property.
///
23
/// Use [PreferredSize] to give a preferred size to an arbitrary widget.
24 25 26 27 28
// (We ignore `avoid_implementing_value_types` here because the superclass
// doesn't really implement `operator ==`, it just overrides it to _prevent_ it
// from being implemented, which is the exact opposite of the spirit of the
// `avoid_implementing_value_types` lint.)
// ignore: avoid_implementing_value_types
29 30 31 32 33 34
abstract class PreferredSizeWidget implements Widget {
  /// The size this widget would prefer if it were otherwise unconstrained.
  ///
  /// In many cases it's only necessary to define one preferred dimension.
  /// For example the [Scaffold] only depends on its app bar's preferred
  /// height. In that case implementations of this method can just return
35
  /// `new Size.fromHeight(myAppBarHeight)`.
36 37 38
  Size get preferredSize;
}

39
/// A widget with a preferred size.
40
///
41 42 43
/// This widget does not impose any constraints on its child, and it doesn't
/// affect the child's layout in any way. It just advertises a preferred size
/// which can be used by the parent.
44
///
45 46 47 48 49 50 51
/// Parents like [Scaffold] use [PreferredSizeWidget] to require that their
/// children implement that interface. To give a preferred size to an arbitrary
/// widget so that it can be used in a `child` property of that type, this
/// widget, [PreferredSize], can be used.
///
/// Widgets like [AppBar] implement a [PreferredSizeWidget], so that this
/// [PreferredSize] widget is not necessary for them.
52
///
53
/// {@tool dartpad}
54 55 56 57 58
/// This sample shows a custom widget, similar to an [AppBar], which uses a
/// [PreferredSize] widget, with its height set to 80 logical pixels.
/// Changing the [PreferredSize] can be used to change the height
/// of the custom app bar.
///
59
/// ** See code in examples/api/lib/widgets/preferred_size/preferred_size.0.dart **
60 61
/// {@end-tool}
///
62 63 64 65 66 67 68
/// See also:
///
///  * [AppBar.bottom] and [Scaffold.appBar], which require preferred size widgets.
///  * [PreferredSizeWidget], the interface which this widget implements to expose
///    its preferred size.
///  * [AppBar] and [TabBar], which implement PreferredSizeWidget.
class PreferredSize extends StatelessWidget implements PreferredSizeWidget {
69
  /// Creates a widget that has a preferred size that the parent can query.
70
  const PreferredSize({
71
    super.key,
72 73
    required this.child,
    required this.preferredSize,
74
  });
75

76
  /// The widget below this widget in the tree.
77
  ///
78
  /// {@macro flutter.widgets.ProxyWidget.child}
79 80 81 82 83 84 85 86
  final Widget child;

  @override
  final Size preferredSize;

  @override
  Widget build(BuildContext context) => child;
}