grid_tile_bar.dart 3.8 KB
Newer Older
1 2 3 4 5 6
// Copyright 2016 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/widgets.dart';

Adam Barth's avatar
Adam Barth committed
7
import 'colors.dart';
8
import 'theme.dart';
9

10 11 12 13 14
/// A header used in a material design [GridTile].
///
/// Typically used to add a one or two line header or footer on a [GridTile].
///
/// For a one-line header, include a [title] widget. To add a second line, also
15
/// include a [subtitle] widget. Use [leading] or [trailing] to add an icon.
16 17 18 19
///
/// See also:
///
///  * [GridTile]
20
///  * <https://material.io/design/components/image-lists.html#anatomy>
21
class GridTileBar extends StatelessWidget {
22 23 24
  /// Creates a grid tile bar.
  ///
  /// Typically used to with [GridTile].
25
  const GridTileBar({
26 27 28 29 30
    Key key,
    this.backgroundColor,
    this.leading,
    this.title,
    this.subtitle,
31
    this.trailing,
32
  }) : super(key: key);
33

34 35 36
  /// The color to paint behind the child widgets.
  ///
  /// Defaults to transparent.
37
  final Color backgroundColor;
38 39 40 41

  /// A widget to display before the title.
  ///
  /// Typically an [Icon] or an [IconButton] widget.
42
  final Widget leading;
43 44 45 46

  /// The primary content of the list item.
  ///
  /// Typically a [Text] widget.
47
  final Widget title;
48 49 50 51

  /// Additional content displayed below the title.
  ///
  /// Typically a [Text] widget.
52
  final Widget subtitle;
53 54 55 56

  /// A widget to display after the title.
  ///
  /// Typically an [Icon] or an [IconButton] widget.
57
  final Widget trailing;
58

59
  @override
60 61 62
  Widget build(BuildContext context) {
    BoxDecoration decoration;
    if (backgroundColor != null)
63
      decoration = BoxDecoration(color: backgroundColor);
64 65

    final List<Widget> children = <Widget>[];
66
    final EdgeInsetsDirectional padding = EdgeInsetsDirectional.only(
67 68
      start: leading != null ? 8.0 : 16.0,
      end: trailing != null ? 8.0 : 16.0,
69
    );
70

71
    if (leading != null)
72
      children.add(Padding(padding: const EdgeInsetsDirectional.only(end: 8.0), child: leading));
73

74
    final ThemeData theme = Theme.of(context);
75
    final ThemeData darkTheme = ThemeData(
76 77
      brightness: Brightness.dark,
      accentColor: theme.accentColor,
78
      accentColorBrightness: theme.accentColorBrightness,
79
    );
80
    if (title != null && subtitle != null) {
81
      children.add(
82 83
        Expanded(
          child: Column(
84
            mainAxisAlignment: MainAxisAlignment.center,
85
            crossAxisAlignment: CrossAxisAlignment.start,
86
            children: <Widget>[
87
              DefaultTextStyle(
88
                style: darkTheme.textTheme.subhead,
89 90
                softWrap: false,
                overflow: TextOverflow.ellipsis,
91
                child: title,
92
              ),
93
              DefaultTextStyle(
94
                style: darkTheme.textTheme.caption,
95 96
                softWrap: false,
                overflow: TextOverflow.ellipsis,
97 98 99 100
                child: subtitle,
              ),
            ],
          ),
101 102
        )
      );
103
    } else if (title != null || subtitle != null) {
104
      children.add(
105 106
        Expanded(
          child: DefaultTextStyle(
107
            style: darkTheme.textTheme.subhead,
108 109
            softWrap: false,
            overflow: TextOverflow.ellipsis,
110 111
            child: title ?? subtitle,
          ),
112 113 114 115
        )
      );
    }

116
    if (trailing != null)
117
      children.add(Padding(padding: const EdgeInsetsDirectional.only(start: 8.0), child: trailing));
118

119
    return Container(
120 121
      padding: padding,
      decoration: decoration,
122
      height: (title != null && subtitle != null) ? 68.0 : 48.0,
123
      child: Theme(
124
        data: darkTheme,
125
        child: IconTheme.merge(
126
          data: const IconThemeData(color: Colors.white),
127
          child: Row(
128
            crossAxisAlignment: CrossAxisAlignment.center,
129 130 131 132
            children: children,
          ),
        ),
      ),
133 134 135
    );
  }
}