list_item.dart 3.77 KB
Newer Older
Adam Barth's avatar
Adam Barth committed
1 2 3 4 5 6 7
// 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.

import 'package:flutter/widgets.dart';

import 'ink_well.dart';
Hans Muller's avatar
Hans Muller committed
8
import 'theme.dart';
Adam Barth's avatar
Adam Barth committed
9

Hans Muller's avatar
Hans Muller committed
10 11 12 13 14 15 16
/// Material List items are one to three lines of text optionally flanked by icons.
/// Icons are defined with the [left] and [right] parameters. The first line of text
/// is not optional and is specified with [primary]. The value of [secondary] will
/// occupy the space allocated for an aditional line of text, or two lines if
/// isThreeLine: true is specified. If isDense: true is specified then the overall
/// height of this list item and the size of the DefaultTextStyles that wrap
/// the [primary] and [secondary] widget are reduced.
Adam Barth's avatar
Adam Barth committed
17 18 19 20
class ListItem extends StatelessComponent {
  ListItem({
    Key key,
    this.left,
Hans Muller's avatar
Hans Muller committed
21 22
    this.primary,
    this.secondary,
Adam Barth's avatar
Adam Barth committed
23
    this.right,
Hans Muller's avatar
Hans Muller committed
24 25
    this.isThreeLine: false,
    this.isDense: false,
Adam Barth's avatar
Adam Barth committed
26 27 28
    this.onTap,
    this.onLongPress
  }) : super(key: key) {
Hans Muller's avatar
Hans Muller committed
29 30
    assert(primary != null);
    assert(isThreeLine ? secondary != null : true);
Adam Barth's avatar
Adam Barth committed
31 32 33
  }

  final Widget left;
Hans Muller's avatar
Hans Muller committed
34 35
  final Widget primary;
  final Widget secondary;
Adam Barth's avatar
Adam Barth committed
36
  final Widget right;
Hans Muller's avatar
Hans Muller committed
37 38
  final bool isThreeLine;
  final bool isDense;
Adam Barth's avatar
Adam Barth committed
39 40 41
  final GestureTapCallback onTap;
  final GestureLongPressCallback onLongPress;

Hans Muller's avatar
Hans Muller committed
42 43 44 45 46 47 48 49 50 51 52 53
  TextStyle primaryTextStyle(BuildContext context) {
    final TextStyle style = Theme.of(context).text.subhead;
    return isDense ? style.copyWith(fontSize: 13.0) : style;
  }

  TextStyle secondaryTextStyle(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final Color color = theme.text.caption.color;
    final TextStyle style = theme.text.body1;
    return isDense ? style.copyWith(color: color, fontSize: 12.0) : style.copyWith(color: color);
  }

Adam Barth's avatar
Adam Barth committed
54
  Widget build(BuildContext context) {
Hans Muller's avatar
Hans Muller committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    final bool isTwoLine = !isThreeLine && secondary != null;
    final bool isOneLine = !isThreeLine && !isTwoLine;
    double itemHeight;
    if (isOneLine)
      itemHeight = isDense ? 48.0 : 56.0;
    else if (isTwoLine)
      itemHeight = isDense ? 60.0 : 72.0;
    else
      itemHeight = isDense ? 76.0 : 88.0;

    double iconMarginTop = 0.0;
    if (isThreeLine)
      iconMarginTop = isDense ? 8.0 : 16.0;

    // Overall, the list item is a Row() with these children.
    final List<Widget> children = <Widget>[];
Adam Barth's avatar
Adam Barth committed
71 72 73

    if (left != null) {
      children.add(new Container(
Hans Muller's avatar
Hans Muller committed
74
        margin: new EdgeDims.only(right: 16.0, top: iconMarginTop),
Adam Barth's avatar
Adam Barth committed
75
        width: 40.0,
Hans Muller's avatar
Hans Muller committed
76 77 78 79
        child: new Align(
          alignment: new FractionalOffset(0.0, isThreeLine ? 0.0 : 0.5),
          child: left
        )
Adam Barth's avatar
Adam Barth committed
80 81 82
      ));
    }

Hans Muller's avatar
Hans Muller committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
    final Widget primaryLine = new DefaultTextStyle(
      style: primaryTextStyle(context),
      child: primary
    );
    Widget center = primaryLine;
    if (isTwoLine || isThreeLine) {
      center = new Column(
        justifyContent: FlexJustifyContent.collapse,
        alignItems: FlexAlignItems.start,
        children: <Widget>[
          primaryLine,
          new DefaultTextStyle(
            style: secondaryTextStyle(context),
            child: secondary
          )
        ]
      );
    }
Adam Barth's avatar
Adam Barth committed
101 102 103 104 105 106
    children.add(new Flexible(
      child: center
    ));

    if (right != null) {
      children.add(new Container(
Hans Muller's avatar
Hans Muller committed
107 108 109 110 111
        margin: new EdgeDims.only(left: 16.0, top: iconMarginTop),
        child: new Align(
          alignment: new FractionalOffset(1.0, isThreeLine ? 0.0 : 0.5),
          child: right
        )
Adam Barth's avatar
Adam Barth committed
112 113 114
      ));
    }

115 116 117
    return new InkWell(
      onTap: onTap,
      onLongPress: onLongPress,
Hans Muller's avatar
Hans Muller committed
118 119
      child: new Container(
        height: itemHeight,
120
        padding: const EdgeDims.symmetric(horizontal: 16.0),
Hans Muller's avatar
Hans Muller committed
121 122 123 124
        child: new Row(
          alignItems: FlexAlignItems.center,
          children: children
        )
Adam Barth's avatar
Adam Barth committed
125 126 127 128
      )
    );
  }
}