| // 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 'package:flutter/painting.dart'; |
| |
| import 'divider_theme.dart'; |
| import 'theme.dart'; |
| |
| // Examples can assume: |
| // BuildContext context; |
| |
| /// A thin horizontal line, with padding on either side. |
| /// |
| /// In the material design language, this represents a divider. Dividers can be |
| /// used in lists, [Drawer]s, and elsewhere to separate content. |
| /// |
| /// To create a divider between [ListTile] items, consider using |
| /// [ListTile.divideTiles], which is optimized for this case. |
| /// |
| /// The box's total height is controlled by [height]. The appropriate |
| /// padding is automatically computed from the height. |
| /// |
| /// See also: |
| /// |
| /// * [PopupMenuDivider], which is the equivalent but for popup menus. |
| /// * [ListTile.divideTiles], another approach to dividing widgets in a list. |
| /// * <https://material.io/design/components/dividers.html> |
| class Divider extends StatelessWidget { |
| /// Creates a material design divider. |
| /// |
| /// The [height], [thickness], [indent], and [endIndent] must be null or |
| /// non-negative. |
| const Divider({ |
| Key key, |
| this.height, |
| this.thickness, |
| this.indent, |
| this.endIndent, |
| this.color, |
| }) : assert(height == null || height >= 0.0), |
| assert(thickness == null || thickness >= 0.0), |
| assert(indent == null || indent >= 0.0), |
| assert(endIndent == null || endIndent >= 0.0), |
| super(key: key); |
| |
| |
| /// The divider's height extent. |
| /// |
| /// The divider itself is always drawn as a horizontal line that is centered |
| /// within the height specified by this value. |
| /// |
| /// If this is null, then the [DividerThemeData.space] is used. If that is |
| /// also null, then this defaults to 16.0. |
| final double height; |
| |
| /// The thickness of the line drawn within the divider. |
| /// |
| /// A divider with a [thickness] of 0.0 is always drawn as a line with a |
| /// height of exactly one device pixel. |
| /// |
| /// If this is null, then the [DividerThemeData.dividerThickness] is used. If |
| /// that is also null, then this defaults to 0.0. |
| final double thickness; |
| |
| /// The amount of empty space to the leading edge of the divider. |
| /// |
| /// If this is null, then the [DividerThemeData.indent] is used. If that is |
| /// also null, then this defaults to 0.0. |
| final double indent; |
| |
| /// The amount of empty space to the trailing edge of the divider. |
| /// |
| /// If this is null, then the [DividerThemeData.endIndent] is used. If that is |
| /// also null, then this defaults to 0.0. |
| final double endIndent; |
| |
| /// The color to use when painting the line. |
| /// |
| /// If this is null, then the [DividerThemeData.color] is used. If that is |
| /// also null, then [ThemeData.dividerColor] is used. |
| /// |
| /// {@tool sample} |
| /// |
| /// ```dart |
| /// Divider( |
| /// color: Colors.deepOrange, |
| /// ) |
| /// ``` |
| /// {@end-tool} |
| final Color color; |
| |
| /// Computes the [BorderSide] that represents a divider of the specified |
| /// color, or, if there is no specified color, of the default |
| /// [ThemeData.dividerColor] specified in the ambient [Theme]. |
| /// |
| /// The `width` argument can be used to override the default width of the |
| /// divider border, which defaults to 0.0 (a hairline border). |
| /// |
| /// {@tool sample} |
| /// |
| /// This example uses this method to create a box that has a divider above and |
| /// below it. This is sometimes useful with lists, for instance, to separate a |
| /// scrollable section from the rest of the interface. |
| /// |
| /// ```dart |
| /// DecoratedBox( |
| /// decoration: BoxDecoration( |
| /// border: Border( |
| /// top: Divider.createBorderSide(context), |
| /// bottom: Divider.createBorderSide(context), |
| /// ), |
| /// ), |
| /// // child: ... |
| /// ) |
| /// ``` |
| /// {@end-tool} |
| static BorderSide createBorderSide(BuildContext context, { Color color, double width }) { |
| return BorderSide( |
| color: color ?? DividerTheme.of(context).color ?? Theme.of(context).dividerColor, |
| width: width ?? DividerTheme.of(context).thickness ?? 0.0, |
| ); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| final DividerThemeData dividerTheme = DividerTheme.of(context); |
| final double height = this.height ?? dividerTheme.space ?? 16.0; |
| final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0; |
| final double indent = this.indent ?? dividerTheme.indent ?? 0.0; |
| final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0; |
| |
| return SizedBox( |
| height: height, |
| child: Center( |
| child: Container( |
| height: thickness, |
| margin: EdgeInsetsDirectional.only(start: indent, end: endIndent), |
| decoration: BoxDecoration( |
| border: Border( |
| bottom: createBorderSide(context, color: color, width: thickness), |
| ), |
| ), |
| ), |
| ), |
| ); |
| } |
| } |
| |
| /// A thin vertical line, with padding on either side. |
| /// |
| /// In the material design language, this represents a divider. Vertical |
| /// dividers can be used in horizontally scrolling lists, such as a |
| /// [ListView] with [ListView.scrollDirection] set to [Axis.horizontal]. |
| /// |
| /// The box's total width is controlled by [width]. The appropriate |
| /// padding is automatically computed from the width. |
| /// |
| /// See also: |
| /// |
| /// * [ListView.separated], which can be used to generate vertical dividers. |
| /// * <https://material.io/design/components/dividers.html> |
| class VerticalDivider extends StatelessWidget { |
| /// Creates a material design vertical divider. |
| /// |
| /// The [width], [thickness], [indent], and [endIndent] must be null or |
| /// non-negative. |
| const VerticalDivider({ |
| Key key, |
| this.width, |
| this.thickness, |
| this.indent, |
| this.endIndent, |
| this.color, |
| }) : assert(width == null || width >= 0.0), |
| assert(thickness == null || thickness >= 0.0), |
| assert(indent == null || indent >= 0.0), |
| assert(endIndent == null || endIndent >= 0.0), |
| super(key: key); |
| |
| /// The divider's width. |
| /// |
| /// The divider itself is always drawn as a vertical line that is centered |
| /// within the width specified by this value. |
| /// |
| /// If this is null, then the [DividerThemeData.space] is used. If that is |
| /// also null, then this defaults to 16.0. |
| final double width; |
| |
| /// The thickness of the line drawn within the divider. |
| /// |
| /// A divider with a [thickness] of 0.0 is always drawn as a line with a |
| /// width of exactly one device pixel. |
| /// |
| /// If this is null, then the [DividerThemeData.thickness] is used which |
| /// defaults to 0.0. |
| final double thickness; |
| |
| /// The amount of empty space on top of the divider. |
| /// |
| /// If this is null, then the [DividerThemeData.indent] is used. If that is |
| /// also null, then this defaults to 0.0. |
| final double indent; |
| |
| /// The amount of empty space under the divider. |
| /// |
| /// If this is null, then the [DividerThemeData.endIndent] is used. If that is |
| /// also null, then this defaults to 0.0. |
| final double endIndent; |
| |
| /// The color to use when painting the line. |
| /// |
| /// If this is null, then the [DividerThemeData.color] is used. If that is |
| /// also null, then [ThemeData.dividerColor] is used. |
| /// |
| /// {@tool sample} |
| /// |
| /// ```dart |
| /// Divider( |
| /// color: Colors.deepOrange, |
| /// ) |
| /// ``` |
| /// {@end-tool} |
| final Color color; |
| |
| @override |
| Widget build(BuildContext context) { |
| final DividerThemeData dividerTheme = DividerTheme.of(context); |
| final double width = this.width ?? dividerTheme.space ?? 16.0; |
| final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0; |
| final double indent = this.indent ?? dividerTheme.indent ?? 0.0; |
| final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0; |
| |
| return SizedBox( |
| width: width, |
| child: Center( |
| child: Container( |
| width: thickness, |
| margin: EdgeInsetsDirectional.only(top: indent, bottom: endIndent), |
| decoration: BoxDecoration( |
| border: Border( |
| left: Divider.createBorderSide(context, color: color, width: thickness), |
| ), |
| ), |
| ), |
| ), |
| ); |
| } |
| } |