Skip to content

Commit 13844aa

Browse files
authored
[Material] Create theme for Dividers to enable customization of thickness (flutter#38621)
1 parent 95b5106 commit 13844aa

File tree

6 files changed

+554
-43
lines changed

6 files changed

+554
-43
lines changed

packages/flutter/lib/material.dart

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export 'src/material/debug.dart';
5050
export 'src/material/dialog.dart';
5151
export 'src/material/dialog_theme.dart';
5252
export 'src/material/divider.dart';
53+
export 'src/material/divider_theme.dart';
5354
export 'src/material/drawer.dart';
5455
export 'src/material/drawer_header.dart';
5556
export 'src/material/dropdown.dart';

packages/flutter/lib/src/material/divider.dart

+89-39
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
import 'package:flutter/widgets.dart';
66
import 'package:flutter/painting.dart';
77

8+
import 'divider_theme.dart';
89
import 'theme.dart';
910

1011
// Examples can assume:
1112
// BuildContext context;
1213

13-
/// A one device pixel thick horizontal line, with padding on either
14-
/// side.
14+
/// A thin horizontal line, with padding on either side.
1515
///
1616
/// In the material design language, this represents a divider. Dividers can be
1717
/// used in lists, [Drawer]s, and elsewhere to separate content.
1818
///
19-
/// To create a one-pixel divider between [ListTile] items, consider using
19+
/// To create a divider between [ListTile] items, consider using
2020
/// [ListTile.divideTiles], which is optimized for this case.
2121
///
2222
/// The box's total height is controlled by [height]. The appropriate
@@ -30,36 +30,56 @@ import 'theme.dart';
3030
class Divider extends StatelessWidget {
3131
/// Creates a material design divider.
3232
///
33-
/// The height must be positive.
33+
/// The [height], [thickness], [indent], and [endIndent] must be null or
34+
/// non-negative.
3435
const Divider({
3536
Key key,
36-
this.height = 16.0,
37-
this.indent = 0.0,
38-
this.endIndent = 0.0,
37+
this.height,
38+
this.thickness,
39+
this.indent,
40+
this.endIndent,
3941
this.color,
40-
}) : assert(height >= 0.0),
42+
}) : assert(height == null || height >= 0.0),
43+
assert(thickness == null || thickness >= 0.0),
44+
assert(indent == null || indent >= 0.0),
45+
assert(endIndent == null || endIndent >= 0.0),
4146
super(key: key);
4247

4348

4449
/// The divider's height extent.
4550
///
46-
/// The divider itself is always drawn as one device pixel thick horizontal
47-
/// line that is centered within the height specified by this value.
51+
/// The divider itself is always drawn as a horizontal line that is centered
52+
/// within the height specified by this value.
4853
///
49-
/// A divider with a [height] of 0.0 is always drawn as a line with a height
50-
/// of exactly one device pixel, without any padding around it.
54+
/// If this is null, then the [DividerThemeData.space] is used. If that is
55+
/// also null, then this defaults to 16.0.
5156
final double height;
5257

53-
/// The amount of empty space to the left of the divider.
58+
/// The thickness of the line drawn within the divider.
59+
///
60+
/// A divider with a [thickness] of 0.0 is always drawn as a line with a
61+
/// height of exactly one device pixel.
62+
///
63+
/// If this is null, then the [DividerThemeData.dividerThickness] is used. If
64+
/// that is also null, then this defaults to 0.0.
65+
final double thickness;
66+
67+
/// The amount of empty space to the leading edge of the divider.
68+
///
69+
/// If this is null, then the [DividerThemeData.indent] is used. If that is
70+
/// also null, then this defaults to 0.0.
5471
final double indent;
5572

56-
/// The amount of empty space to the right of the divider.
73+
/// The amount of empty space to the trailing edge of the divider.
74+
///
75+
/// If this is null, then the [DividerThemeData.endIndent] is used. If that is
76+
/// also null, then this defaults to 0.0.
5777
final double endIndent;
5878

5979
/// The color to use when painting the line.
6080
///
61-
/// Defaults to the current theme's divider color, given by
62-
/// [ThemeData.dividerColor].
81+
/// If this is null, then the [DividerThemeData.color] is used. If that is
82+
/// also null, then [ThemeData.dividerColor] is used.
6383
///
6484
/// {@tool sample}
6585
///
@@ -76,7 +96,7 @@ class Divider extends StatelessWidget {
7696
/// [ThemeData.dividerColor] specified in the ambient [Theme].
7797
///
7898
/// The `width` argument can be used to override the default width of the
79-
/// divider border, which is usually 0.0 (a hairline border).
99+
/// divider border, which defaults to 0.0 (a hairline border).
80100
///
81101
/// {@tool sample}
82102
///
@@ -96,25 +116,30 @@ class Divider extends StatelessWidget {
96116
/// )
97117
/// ```
98118
/// {@end-tool}
99-
static BorderSide createBorderSide(BuildContext context, { Color color, double width = 0.0 }) {
100-
assert(width != null);
119+
static BorderSide createBorderSide(BuildContext context, { Color color, double width }) {
101120
return BorderSide(
102-
color: color ?? Theme.of(context).dividerColor,
103-
width: width,
121+
color: color ?? DividerTheme.of(context).color ?? Theme.of(context).dividerColor,
122+
width: width ?? DividerTheme.of(context).thickness ?? 0.0,
104123
);
105124
}
106125

107126
@override
108127
Widget build(BuildContext context) {
128+
final DividerThemeData dividerTheme = DividerTheme.of(context);
129+
final double height = this.height ?? dividerTheme.space ?? 16.0;
130+
final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0;
131+
final double indent = this.indent ?? dividerTheme.indent ?? 0.0;
132+
final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0;
133+
109134
return SizedBox(
110135
height: height,
111136
child: Center(
112137
child: Container(
113-
height: 0.0,
138+
height: thickness,
114139
margin: EdgeInsetsDirectional.only(start: indent, end: endIndent),
115140
decoration: BoxDecoration(
116141
border: Border(
117-
bottom: createBorderSide(context, color: color),
142+
bottom: createBorderSide(context, color: color, width: thickness),
118143
),
119144
),
120145
),
@@ -123,8 +148,7 @@ class Divider extends StatelessWidget {
123148
}
124149
}
125150

126-
/// A one device pixel thick vertical line, with padding on either
127-
/// side.
151+
/// A thin vertical line, with padding on either side.
128152
///
129153
/// In the material design language, this represents a divider. Vertical
130154
/// dividers can be used in horizontally scrolling lists, such as a
@@ -138,37 +162,57 @@ class Divider extends StatelessWidget {
138162
/// * [ListView.separated], which can be used to generate vertical dividers.
139163
/// * <https://material.io/design/components/dividers.html>
140164
class VerticalDivider extends StatelessWidget {
141-
/// Creates a material design divider.
165+
/// Creates a material design vertical divider.
142166
///
143-
/// The width must be positive.
167+
/// The [width], [thickness], [indent], and [endIndent] must be null or
168+
/// non-negative.
144169
const VerticalDivider({
145170
Key key,
146-
this.width = 16.0,
147-
this.indent = 0.0,
148-
this.endIndent = 0.0,
171+
this.width,
172+
this.thickness,
173+
this.indent,
174+
this.endIndent,
149175
this.color,
150-
}) : assert(width >= 0.0),
176+
}) : assert(width == null || width >= 0.0),
177+
assert(thickness == null || thickness >= 0.0),
178+
assert(indent == null || indent >= 0.0),
179+
assert(endIndent == null || endIndent >= 0.0),
151180
super(key: key);
152181

153182
/// The divider's width.
154183
///
155-
/// The divider itself is always drawn as one device pixel thick
156-
/// line that is centered within the width specified by this value.
184+
/// The divider itself is always drawn as a vertical line that is centered
185+
/// within the width specified by this value.
157186
///
158-
/// A divider with a [width] of 0.0 is always drawn as a line with a width
159-
/// of exactly one device pixel, without any padding around it.
187+
/// If this is null, then the [DividerThemeData.space] is used. If that is
188+
/// also null, then this defaults to 16.0.
160189
final double width;
161190

191+
/// The thickness of the line drawn within the divider.
192+
///
193+
/// A divider with a [thickness] of 0.0 is always drawn as a line with a
194+
/// width of exactly one device pixel.
195+
///
196+
/// If this is null, then the [DividerThemeData.thickness] is used which
197+
/// defaults to 0.0.
198+
final double thickness;
199+
162200
/// The amount of empty space on top of the divider.
201+
///
202+
/// If this is null, then the [DividerThemeData.indent] is used. If that is
203+
/// also null, then this defaults to 0.0.
163204
final double indent;
164205

165206
/// The amount of empty space under the divider.
207+
///
208+
/// If this is null, then the [DividerThemeData.endIndent] is used. If that is
209+
/// also null, then this defaults to 0.0.
166210
final double endIndent;
167211

168212
/// The color to use when painting the line.
169213
///
170-
/// Defaults to the current theme's divider color, given by
171-
/// [ThemeData.dividerColor].
214+
/// If this is null, then the [DividerThemeData.color] is used. If that is
215+
/// also null, then [ThemeData.dividerColor] is used.
172216
///
173217
/// {@tool sample}
174218
///
@@ -182,15 +226,21 @@ class VerticalDivider extends StatelessWidget {
182226

183227
@override
184228
Widget build(BuildContext context) {
229+
final DividerThemeData dividerTheme = DividerTheme.of(context);
230+
final double width = this.width ?? dividerTheme.space ?? 16.0;
231+
final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0;
232+
final double indent = this.indent ?? dividerTheme.indent ?? 0.0;
233+
final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0;
234+
185235
return SizedBox(
186236
width: width,
187237
child: Center(
188238
child: Container(
189-
width: 0.0,
239+
width: thickness,
190240
margin: EdgeInsetsDirectional.only(top: indent, bottom: endIndent),
191241
decoration: BoxDecoration(
192242
border: Border(
193-
left: Divider.createBorderSide(context, color: color),
243+
left: Divider.createBorderSide(context, color: color, width: thickness),
194244
),
195245
),
196246
),

0 commit comments

Comments
 (0)