drawer_item.dart 3.86 KB
Newer Older
1 2 3 4
// Copyright 2015 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.

5
import 'package:flutter/widgets.dart';
6

7
import 'colors.dart';
8
import 'constants.dart';
9
import 'debug.dart';
10
import 'icon.dart';
Ian Hickson's avatar
Ian Hickson committed
11 12 13
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'image_icon.dart';
14 15
import 'ink_well.dart';
import 'theme.dart';
16

17 18 19 20
/// An item in a material design drawer.
///
/// Part of the material design [Drawer].
///
21 22
/// Requires one of its ancestors to be a [Material] widget. This condition is
/// satisfied by putting the [DrawerItem] in a [Drawer].
23 24
///
/// See also:
25
///
26 27
///  * [Drawer]
///  * [DrawerHeader]
28
///  * <https://material.google.com/patterns/navigation-drawer.html>
29
class DrawerItem extends StatelessWidget {
30 31 32
  /// Creates a material design drawer item.
  ///
  /// Requires one of its ancestors to be a [Material] widget.
33 34
  const DrawerItem({
    Key key,
Ian Hickson's avatar
Ian Hickson committed
35
    this.icon: const Icon(null),
36 37 38 39
    this.child,
    this.onPressed,
    this.selected: false
  }) : super(key: key);
40

41
  /// The icon to display before the child widget.
Ian Hickson's avatar
Ian Hickson committed
42 43 44 45 46 47 48
  ///
  /// The size and color of the icon is configured automatically using an
  /// [IconTheme] and therefore do not need to be explicitly given in the
  /// icon widget.
  ///
  /// See [Icon], [ImageIcon].
  final Widget icon;
49 50

  /// The widget below this widget in the tree.
51
  final Widget child;
52

53
  /// Called when the user taps this drawer item.
54 55
  ///
  /// If null, the drawer item is displayed as disabled.
56 57
  ///
  /// To close the [Drawer] when an item is pressed, call [Navigator.pop].
58
  final VoidCallback onPressed;
59

60 61 62 63
  /// Whether this drawer item is currently selected.
  ///
  /// The currently selected item is highlighted to distinguish it from other
  /// drawer items.
64
  final bool selected;
65

Adam Barth's avatar
Adam Barth committed
66
  Color _getIconColor(ThemeData themeData) {
67
    switch (themeData.brightness) {
68
      case Brightness.light:
69 70 71 72 73
        if (selected)
          return themeData.primaryColor;
        if (onPressed == null)
          return Colors.black26;
        return Colors.black45;
74
      case Brightness.dark:
75 76 77 78
        if (selected)
          return themeData.accentColor;
        if (onPressed == null)
          return Colors.white30;
79
        return null; // use default icon theme color unmodified
80
    }
pq's avatar
pq committed
81 82
    assert(themeData.brightness != null);
    return null;
83 84
  }

85
  TextStyle _getTextStyle(ThemeData themeData) {
86
    TextStyle result = themeData.textTheme.body2;
87
    if (selected) {
88
      switch (themeData.brightness) {
89
        case Brightness.light:
90
          return result.copyWith(color: themeData.primaryColor);
91
        case Brightness.dark:
92 93
          return result.copyWith(color: themeData.accentColor);
      }
94
    }
95 96 97
    return result;
  }

98
  @override
99
  Widget build(BuildContext context) {
100
    assert(debugCheckHasMaterial(context));
101
    ThemeData themeData = Theme.of(context);
102

103
    List<Widget> children = <Widget>[];
104
    if (icon != null) {
105
      children.add(
106
        new Padding(
107
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
Ian Hickson's avatar
Ian Hickson committed
108 109 110 111 112 113 114
          child: new IconTheme.merge(
            context: context,
            data: new IconThemeData(
              color: _getIconColor(themeData),
              size: 24.0
            ),
            child: icon
115
          )
116 117 118
        )
      );
    }
119 120
    if (child != null) {
      children.add(
121
        new Expanded(
122 123 124 125 126 127 128
          child: new Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: new AnimatedDefaultTextStyle(
              style: _getTextStyle(themeData),
              duration: kThemeChangeDuration,
              child: child
            )
129 130
          )
        )
131 132
      );
    }
133

Hixie's avatar
Hixie committed
134 135 136 137 138 139 140
    return new MergeSemantics(
      child: new Container(
        height: 48.0,
        child: new InkWell(
          onTap: onPressed,
          child: new Row(children: children)
        )
141 142 143
      )
    );
  }
144

145
}