From 0bb1e573fce0a32c28d1bd3caf26e53405604f48 Mon Sep 17 00:00:00 2001 From: Per Classon Date: Tue, 8 Sep 2020 15:28:13 +0200 Subject: [PATCH] Revert "Add DataTableTheme to allow for themable DataTables (#64316)" (#65382) This reverts commit cb4b8677219482e3378b1b6bfeff1241a453ccb6. --- packages/flutter/lib/material.dart | 1 - .../flutter/lib/src/material/data_table.dart | 293 +++++------------- .../lib/src/material/data_table_theme.dart | 250 --------------- .../src/material/paginated_data_table.dart | 1 - .../flutter/lib/src/material/theme_data.dart | 17 +- .../test/material/data_table_test.dart | 66 +--- .../test/material/data_table_theme_test.dart | 268 ---------------- .../test/material/theme_data_test.dart | 2 - 8 files changed, 82 insertions(+), 816 deletions(-) delete mode 100644 packages/flutter/lib/src/material/data_table_theme.dart delete mode 100644 packages/flutter/test/material/data_table_theme_test.dart diff --git a/packages/flutter/lib/material.dart b/packages/flutter/lib/material.dart index 1ef4259d2a6..aa7c82b212a 100644 --- a/packages/flutter/lib/material.dart +++ b/packages/flutter/lib/material.dart @@ -52,7 +52,6 @@ export 'src/material/constants.dart'; export 'src/material/curves.dart'; export 'src/material/data_table.dart'; export 'src/material/data_table_source.dart'; -export 'src/material/data_table_theme.dart'; export 'src/material/debug.dart'; export 'src/material/dialog.dart'; export 'src/material/dialog_theme.dart'; diff --git a/packages/flutter/lib/src/material/data_table.dart b/packages/flutter/lib/src/material/data_table.dart index 41122fd01fa..98cc73d2461 100644 --- a/packages/flutter/lib/src/material/data_table.dart +++ b/packages/flutter/lib/src/material/data_table.dart @@ -11,12 +11,12 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'checkbox.dart'; +import 'colors.dart'; import 'constants.dart'; import 'debug.dart'; import 'divider.dart'; import 'dropdown.dart'; import 'icons.dart'; -import 'ink_decoration.dart'; import 'ink_well.dart'; import 'material.dart'; import 'material_state.dart'; @@ -414,27 +414,25 @@ class DataTable extends StatelessWidget { this.sortColumnIndex, this.sortAscending = true, this.onSelectAll, - this.decoration, - this.dataRowColor, - this.dataRowHeight, - this.dataTextStyle, - this.headingRowColor, - this.headingRowHeight, - this.headingTextStyle, - this.horizontalMargin, - this.columnSpacing, + this.dataRowHeight = kMinInteractiveDimension, + this.headingRowHeight = 56.0, + this.horizontalMargin = 24.0, + this.columnSpacing = 56.0, this.showCheckboxColumn = true, - this.showBottomBorder = false, - this.dividerThickness, + this.dividerThickness = 1.0, @required this.rows, }) : assert(columns != null), assert(columns.isNotEmpty), assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)), assert(sortAscending != null), + assert(dataRowHeight != null), + assert(headingRowHeight != null), + assert(horizontalMargin != null), + assert(columnSpacing != null), assert(showCheckboxColumn != null), assert(rows != null), assert(!rows.any((DataRow row) => row.cells.length != columns.length)), - assert(dividerThickness == null || dividerThickness >= 0), + assert(dividerThickness != null && dividerThickness >= 0), _onlyTextColumn = _initOnlyTextColumn(columns), super(key: key); @@ -477,117 +475,27 @@ class DataTable extends StatelessWidget { /// row is selectable. final ValueSetter onSelectAll; - /// {@template flutter.material.dataTable.decoration} - /// The background and border decoration for the table. - /// {@endtemplate} - /// - /// By default there is no decoration. - final BoxDecoration decoration; - - /// {@template flutter.material.dataTable.dataRowColor} - /// The background color for the data rows. - /// - /// The effective background color can be made to depend on the - /// [MaterialState] state, i.e. if the row is selected, pressed, hovered, - /// focused, disabled or enabled. The color is painted as an overlay to the - /// row. To make sure that the row's [InkWell] is visible (when pressed, - /// hovered and focused), it is recommended to use a translucent background - /// color. - /// {@endtemplate} - /// - /// By default, the background color is transparent unless selected. Selected - /// rows have a grey translucent color. To set a different color for - /// individual rows, see [DataRow.color]. - /// - /// {@template flutter.material.dataTable.dataRowColorCode} - /// ```dart - /// DataTable( - /// dataRowColor: MaterialStateProperty.resolveWith((Set states) { - /// if (states.contains(MaterialState.selected)) - /// return Theme.of(context).colorScheme.primary.withOpacity(0.08); - /// return null; // Use the default value. - /// }), - /// ) - /// ``` - /// - /// See also: - /// - /// * The Material Design specification for overlay colors and how they - /// match a component's state: - /// . - /// {@endtemplate} - final MaterialStateProperty dataRowColor; - - /// {@template flutter.material.dataTable.dataRowHeight} /// The height of each row (excluding the row that contains column headings). - /// {@endtemplate} /// - /// This value defaults to [kMinInteractiveDimension] to adhere to the Material + /// This value defaults to kMinInteractiveDimension to adhere to the Material /// Design specifications. final double dataRowHeight; - /// {@template flutter.material.dataTable.dataTextStyle} - /// The text style for data rows. - /// {@endtemplate} - /// - /// By default, the text style is [TextTheme.bodyText2]. - final TextStyle dataTextStyle; - - /// {@template flutter.material.dataTable.headingRowColor} - /// The background color for the heading row. - /// - /// The effective background color can be made to depend on the - /// [MaterialState] state, i.e. if the row is pressed, hovered, focused when - /// sorted. The color is painted as an overlay to the row. To make sure that - /// the row's [InkWell] is visible (when pressed, hovered and focused), it is - /// recommended to use a translucent color. - /// - /// ```dart - /// DataTable( - /// headingRowColor: MaterialStateProperty.resolveWith((Set states) { - /// if (states.contains(MaterialState.hovered)) - /// return Theme.of(context).colorScheme.primary.withOpacity(0.08); - /// return null; // Use the default value. - /// }), - /// ) - /// ``` - /// - /// See also: - /// - /// * The Material Design specification for overlay colors and how they - /// match a component's state: - /// . - /// {@endtemplate} - final MaterialStateProperty headingRowColor; - - /// {@template flutter.material.dataTable.headingRowHeight} /// The height of the heading row. - /// {@endtemplate} /// /// This value defaults to 56.0 to adhere to the Material Design specifications. final double headingRowHeight; - /// {@template flutter.material.dataTable.headingTextStyle} - /// The text style for the heading row. - /// {@endtemplate} - /// - /// By default, the text style is [TextTheme.subtitle2]. - final TextStyle headingTextStyle; - - /// {@template flutter.material.dataTable.horizontalMargin} /// The horizontal margin between the edges of the table and the content /// in the first and last cells of each row. /// /// When a checkbox is displayed, it is also the margin between the checkbox /// the content in the first data column. - /// {@endtemplate} /// /// This value defaults to 24.0 to adhere to the Material Design specifications. final double horizontalMargin; - /// {@template flutter.material.dataTable.columnSpacing} /// The horizontal margin between the contents of each data column. - /// {@endtemplate} /// /// This value defaults to 56.0 to adhere to the Material Design specifications. final double columnSpacing; @@ -609,20 +517,6 @@ class DataTable extends StatelessWidget { /// Must be non-null, but may be empty. final List rows; - /// {@template flutter.material.dataTable.dividerThickness} - /// The width of the divider that appears between [TableRow]s. - /// - /// Must be greater than or equal to zero. - /// {@endtemplate} - /// This value defaults to 1.0. - final double dividerThickness; - - /// Whether a border at the bottom of the table is displayed. - /// - /// By default, a border is not shown at the bottom to allow for a border - /// around the table set with [DataTable.decoration]. - final bool showBottomBorder; - // Set by the constructor to the index of the only Column that is // non-numeric, if there is exactly one, otherwise null. final int _onlyTextColumn; @@ -657,45 +551,29 @@ class DataTable extends StatelessWidget { } } - /// The default height of the heading row. - static const double _headingRowHeight = 56.0; - - /// The default horizontal margin between the edges of the table and the content - /// in the first and last cells of each row. - static const double _horizontalMargin = 24.0; - - /// The default horizontal margin between the contents of each data column. - static const double _columnSpacing = 56.0; - - /// The default padding between the heading content and sort arrow. static const double _sortArrowPadding = 2.0; - - /// The default divider thickness. - static const double _dividerThickness = 1.0; - + static const double _headingFontSize = 12.0; static const Duration _sortArrowAnimationDuration = Duration(milliseconds: 150); static const Color _grey100Opacity = Color(0x0A000000); // Grey 100 as opacity instead of solid color static const Color _grey300Opacity = Color(0x1E000000); // Dark theme variant is just a guess. + /// The width of the divider that appears between [TableRow]s. + /// + /// Must be non-null and greater than or equal to zero. + /// This value defaults to 1.0. + final double dividerThickness; + Widget _buildCheckbox({ - BuildContext context, Color activeColor, bool checked, VoidCallback onRowTap, ValueChanged onCheckboxChanged, MaterialStateProperty overlayColor, }) { - final ThemeData themeData = Theme.of(context); - final double effectiveHorizontalMargin = horizontalMargin - ?? themeData.dataTableTheme.horizontalMargin - ?? _horizontalMargin; Widget contents = Semantics( container: true, child: Padding( - padding: EdgeInsetsDirectional.only( - start: effectiveHorizontalMargin, - end: effectiveHorizontalMargin / 2.0, - ), + padding: EdgeInsetsDirectional.only(start: horizontalMargin, end: horizontalMargin / 2.0), child: Center( child: Checkbox( activeColor: activeColor, @@ -727,37 +605,39 @@ class DataTable extends StatelessWidget { VoidCallback onSort, bool sorted, bool ascending, - MaterialStateProperty overlayColor, }) { - final ThemeData themeData = Theme.of(context); + List arrowWithPadding() { + return onSort == null ? const [] : [ + _SortArrow( + visible: sorted, + up: sorted ? ascending : null, + duration: _sortArrowAnimationDuration, + ), + const SizedBox(width: _sortArrowPadding), + ]; + } label = Row( textDirection: numeric ? TextDirection.rtl : null, children: [ label, - if (onSort != null) - ...[ - _SortArrow( - visible: sorted, - up: sorted ? ascending : null, - duration: _sortArrowAnimationDuration, - ), - const SizedBox(width: _sortArrowPadding), - ], + ...arrowWithPadding(), ], ); - - final TextStyle effectiveHeadingTextStyle = headingTextStyle - ?? themeData.dataTableTheme.headingTextStyle - ?? themeData.textTheme.subtitle2; - final double effectiveHeadingRowHeight = headingRowHeight - ?? themeData.dataTableTheme.headingRowHeight - ?? _headingRowHeight; label = Container( padding: padding, - height: effectiveHeadingRowHeight, + height: headingRowHeight, alignment: numeric ? Alignment.centerRight : AlignmentDirectional.centerStart, child: AnimatedDefaultTextStyle( - style: effectiveHeadingTextStyle, + style: TextStyle( + // TODO(hansmuller): This should use the information provided by + // textTheme/DataTableTheme, https://github.com/flutter/flutter/issues/56079 + fontWeight: FontWeight.w500, + fontSize: _headingFontSize, + height: math.min(1.0, headingRowHeight / _headingFontSize), + color: (Theme.of(context).brightness == Brightness.light) + ? ((onSort != null && sorted) ? Colors.black87 : Colors.black54) + : ((onSort != null && sorted) ? Colors.white : Colors.white70), + ), softWrap: false, duration: _sortArrowAnimationDuration, child: label, @@ -769,12 +649,10 @@ class DataTable extends StatelessWidget { child: label, ); } - // TODO(dkwingsmt): Only wrap Inkwell if onSort != null. Blocked by // https://github.com/flutter/flutter/issues/51152 label = InkWell( onTap: onSort, - overlayColor: overlayColor, child: label, ); return label; @@ -791,7 +669,7 @@ class DataTable extends StatelessWidget { VoidCallback onSelectChanged, MaterialStateProperty overlayColor, }) { - final ThemeData themeData = Theme.of(context); + final bool isLightTheme = Theme.of(context).brightness == Brightness.light; if (showEditIcon) { const Widget icon = Icon(Icons.edit, size: 18.0); label = Expanded(child: label); @@ -800,22 +678,25 @@ class DataTable extends StatelessWidget { children: [ label, icon ], ); } - - final TextStyle effectiveDataTextStyle = dataTextStyle - ?? themeData.dataTableTheme.dataTextStyle - ?? themeData.textTheme.bodyText2; - final double effectiveDataRowHeight = dataRowHeight - ?? themeData.dataTableTheme.dataRowHeight - ?? kMinInteractiveDimension; label = Container( padding: padding, - height: effectiveDataRowHeight, + height: dataRowHeight, alignment: numeric ? Alignment.centerRight : AlignmentDirectional.centerStart, child: DefaultTextStyle( - style: effectiveDataTextStyle.copyWith( - color: placeholder ? effectiveDataTextStyle.color.withOpacity(0.6) : null, + style: TextStyle( + // TODO(hansmuller): This should use the information provided by + // textTheme/DataTableTheme, https://github.com/flutter/flutter/issues/56079 + fontSize: 13.0, + color: isLightTheme + ? (placeholder ? Colors.black38 : Colors.black87) + : (placeholder ? Colors.white38 : Colors.white70), + ), + child: IconTheme.merge( + data: IconThemeData( + color: isLightTheme ? Colors.black54 : Colors.white70, + ), + child: DropdownButtonHideUnderline(child: label), ), - child: DropdownButtonHideUnderline(child: label), ), ); if (onTap != null) { @@ -839,16 +720,12 @@ class DataTable extends StatelessWidget { assert(!_debugInteractive || debugCheckHasMaterial(context)); final ThemeData theme = Theme.of(context); - final MaterialStateProperty effectiveHeadingRowColor = headingRowColor - ?? theme.dataTableTheme.headingRowColor; - final MaterialStateProperty effectiveDataRowColor = dataRowColor - ?? theme.dataTableTheme.dataRowColor; final MaterialStateProperty defaultRowColor = MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.selected)) { + // TODO(per): Add theming support for DataTable, https://github.com/flutter/flutter/issues/56079. // The color has to be transparent so you can see the ink on // the [Material]. - // TODO(perclasson): Align with Material specs, use translucent primary color: https://github.com/flutter/flutter/issues/64314. return (Theme.of(context).brightness == Brightness.light) ? _grey100Opacity : _grey300Opacity; } @@ -858,12 +735,6 @@ class DataTable extends StatelessWidget { final bool anyRowSelectable = rows.any((DataRow row) => row.onSelectChanged != null); final bool displayCheckboxColumn = showCheckboxColumn && anyRowSelectable; final bool allChecked = displayCheckboxColumn && !rows.any((DataRow row) => row.onSelectChanged != null && !row.selected); - final double effectiveHorizontalMargin = horizontalMargin - ?? theme.dataTableTheme.horizontalMargin - ?? _horizontalMargin; - final double effectiveColumnSpacing = columnSpacing - ?? theme.dataTableTheme.columnSpacing - ?? _columnSpacing; final List tableColumns = List(columns.length + (displayCheckboxColumn ? 1 : 0)); final List tableRows = List.generate( @@ -877,22 +748,13 @@ class DataTable extends StatelessWidget { if (isDisabled) MaterialState.disabled, }; - final Color resolvedDataRowColor = index > 0 ? (rows[index - 1].color ?? effectiveDataRowColor)?.resolve(states) : null; - final Color resolvedHeadingRowColor = effectiveHeadingRowColor?.resolve({}); - final Color rowColor = index > 0 ? resolvedDataRowColor : resolvedHeadingRowColor; - final BorderSide borderSide = Divider.createBorderSide( - context, - width: dividerThickness - ?? theme.dataTableTheme.dividerThickness - ?? _dividerThickness, - ); - final Border border = showBottomBorder - ? Border(bottom: borderSide) - : index == 0 ? null : Border(top: borderSide); + final Color rowColor = index > 0 ? rows[index - 1].color?.resolve(states) : null; return TableRow( key: index == 0 ? _headingRowKey : rows[index - 1].key, decoration: BoxDecoration( - border: border, + border: Border( + bottom: Divider.createBorderSide(context, width: dividerThickness), + ), color: rowColor ?? defaultRowColor.resolve(states), ), children: List(tableColumns.length), @@ -904,9 +766,8 @@ class DataTable extends StatelessWidget { int displayColumnIndex = 0; if (displayCheckboxColumn) { - tableColumns[0] = FixedColumnWidth(effectiveHorizontalMargin + Checkbox.width + effectiveHorizontalMargin / 2.0); + tableColumns[0] = FixedColumnWidth(horizontalMargin + Checkbox.width + horizontalMargin / 2.0); tableRows[0].children[0] = _buildCheckbox( - context: context, activeColor: theme.accentColor, checked: allChecked, onCheckboxChanged: _handleSelectAll, @@ -914,12 +775,11 @@ class DataTable extends StatelessWidget { rowIndex = 1; for (final DataRow row in rows) { tableRows[rowIndex].children[0] = _buildCheckbox( - context: context, activeColor: theme.accentColor, checked: row.selected, onRowTap: () => row.onSelectChanged != null ? row.onSelectChanged(!row.selected) : null , onCheckboxChanged: row.onSelectChanged, - overlayColor: row.color ?? effectiveDataRowColor, + overlayColor: row.color, ); rowIndex += 1; } @@ -931,18 +791,18 @@ class DataTable extends StatelessWidget { double paddingStart; if (dataColumnIndex == 0 && displayCheckboxColumn) { - paddingStart = effectiveHorizontalMargin / 2.0; + paddingStart = horizontalMargin / 2.0; } else if (dataColumnIndex == 0 && !displayCheckboxColumn) { - paddingStart = effectiveHorizontalMargin; + paddingStart = horizontalMargin; } else { - paddingStart = effectiveColumnSpacing / 2.0; + paddingStart = columnSpacing / 2.0; } double paddingEnd; if (dataColumnIndex == columns.length - 1) { - paddingEnd = effectiveHorizontalMargin; + paddingEnd = horizontalMargin; } else { - paddingEnd = effectiveColumnSpacing / 2.0; + paddingEnd = columnSpacing / 2.0; } final EdgeInsetsDirectional padding = EdgeInsetsDirectional.only( @@ -963,7 +823,6 @@ class DataTable extends StatelessWidget { onSort: column.onSort != null ? () => column.onSort(dataColumnIndex, sortColumnIndex != dataColumnIndex || !sortAscending) : null, sorted: dataColumnIndex == sortColumnIndex, ascending: sortAscending, - overlayColor: effectiveHeadingRowColor, ); rowIndex = 1; for (final DataRow row in rows) { @@ -977,19 +836,16 @@ class DataTable extends StatelessWidget { showEditIcon: cell.showEditIcon, onTap: cell.onTap, onSelectChanged: () => row.onSelectChanged != null ? row.onSelectChanged(!row.selected) : null, - overlayColor: row.color ?? effectiveDataRowColor, + overlayColor: row.color, ); rowIndex += 1; } displayColumnIndex += 1; } - return Ink( - decoration: decoration ?? theme.dataTableTheme.decoration, - child: Table( - columnWidths: tableColumns.asMap(), - children: tableRows, - ), + return Table( + columnWidths: tableColumns.asMap(), + children: tableRows, ); } } @@ -1179,9 +1035,10 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin { transform: Matrix4.rotationZ(_orientationOffset + _orientationAnimation.value) ..setTranslationRaw(0.0, _arrowIconBaselineOffset, 0.0), alignment: Alignment.center, - child: const Icon( + child: Icon( Icons.arrow_upward, size: _arrowIconSize, + color: (Theme.of(context).brightness == Brightness.light) ? Colors.black87 : Colors.white70, ), ), ); diff --git a/packages/flutter/lib/src/material/data_table_theme.dart b/packages/flutter/lib/src/material/data_table_theme.dart deleted file mode 100644 index 595f636664c..00000000000 --- a/packages/flutter/lib/src/material/data_table_theme.dart +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// @dart = 2.8 - -import 'dart:ui' show lerpDouble; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/widgets.dart'; - -import 'material_state.dart'; -import 'theme.dart'; - -/// Defines default property values for descendant [DataTable] -/// widgets. -/// -/// Descendant widgets obtain the current [DataTableThemeData] object -/// using `DataTableTheme.of(context)`. Instances of -/// [DataTableThemeData] can be customized with -/// [DataTableThemeData.copyWith]. -/// -/// Typically a [DataTableThemeData] is specified as part of the -/// overall [Theme] with [ThemeData.dataTableTheme]. -/// -/// All [DataTableThemeData] properties are `null` by default. When -/// null, the [DataTable] will use the values from [ThemeData] if they exist, -/// otherwise it will provide its own defaults based on the overall [Theme]'s -/// textTheme and colorScheme. See the individual [DataTable] properties for -/// details. -/// -/// See also: -/// -/// * [ThemeData], which describes the overall theme information for the -/// application. -@immutable -class DataTableThemeData with Diagnosticable { - /// Creates a theme that can be used for [ThemeData.dataTableTheme]. - const DataTableThemeData({ - this.decoration, - this.dataRowColor, - this.dataRowHeight, - this.dataTextStyle, - this.headingRowColor, - this.headingRowHeight, - this.headingTextStyle, - this.horizontalMargin, - this.columnSpacing, - this.dividerThickness, - }); - - /// {@macro flutter.material.dataTable.decoration} - final Decoration decoration; - - /// {@macro flutter.material.dataTable.dataRowColor} - /// {@macro flutter.material.dataTable.dataRowColorCode} - final MaterialStateProperty dataRowColor; - - /// {@macro flutter.material.dataTable.dataRowHeight} - final double dataRowHeight; - - /// {@macro flutter.material.dataTable.dataTextStyle} - final TextStyle dataTextStyle; - - /// {@macro flutter.material.dataTable.headingRowColor} - final MaterialStateProperty headingRowColor; - - /// {@macro flutter.material.dataTable.headingRowHeight} - final double headingRowHeight; - - /// {@macro flutter.material.dataTable.headingTextStyle} - final TextStyle headingTextStyle; - - /// {@macro flutter.material.dataTable.horizontalMargin} - final double horizontalMargin; - - /// {@macro flutter.material.dataTable.columnSpacing} - final double columnSpacing; - - /// {@macro flutter.material.dataTable.dividerThickness} - final double dividerThickness; - - /// Creates a copy of this object but with the given fields replaced with the - /// new values. - DataTableThemeData copyWith({ - Decoration decoration, - MaterialStateProperty dataRowColor, - double dataRowHeight, - TextStyle dataTextStyle, - MaterialStateProperty headingRowColor, - double headingRowHeight, - TextStyle headingTextStyle, - double horizontalMargin, - double columnSpacing, - double dividerThickness, - }) { - return DataTableThemeData( - decoration: decoration ?? this.decoration, - dataRowColor: dataRowColor ?? this.dataRowColor, - dataRowHeight: dataRowHeight ?? this.dataRowHeight, - dataTextStyle: dataTextStyle ?? this.dataTextStyle, - headingRowColor: headingRowColor ?? this.headingRowColor, - headingRowHeight: headingRowHeight ?? this.headingRowHeight, - headingTextStyle: headingTextStyle ?? this.headingTextStyle, - horizontalMargin: horizontalMargin ?? this.horizontalMargin, - columnSpacing: columnSpacing ?? this.columnSpacing, - dividerThickness: dividerThickness ?? this.dividerThickness, - ); - } - - /// Linearly interpolate between two [DataTableThemeData]s. - /// - /// The argument `t` must not be null. - /// - /// {@macro dart.ui.shadow.lerp} - static DataTableThemeData lerp(DataTableThemeData a, DataTableThemeData b, double t) { - assert(t != null); - return DataTableThemeData( - decoration: Decoration.lerp(a.decoration, b.decoration, t), - dataRowColor: _lerpProperties(a.dataRowColor, b.dataRowColor, t, Color.lerp), - dataRowHeight: lerpDouble(a.dataRowHeight, b.dataRowHeight, t), - dataTextStyle: TextStyle.lerp(a.dataTextStyle, b.dataTextStyle, t), - headingRowColor: _lerpProperties(a.headingRowColor, b.headingRowColor, t, Color.lerp), - headingRowHeight: lerpDouble(a.headingRowHeight, b.headingRowHeight, t), - headingTextStyle: TextStyle.lerp(a.headingTextStyle, b.headingTextStyle, t), - horizontalMargin: lerpDouble(a.horizontalMargin, b.horizontalMargin, t), - columnSpacing: lerpDouble(a.columnSpacing, b.columnSpacing, t), - dividerThickness: lerpDouble(a.dividerThickness, b.dividerThickness, t) - ); - } - - @override - int get hashCode { - return hashValues( - decoration, - dataRowColor, - dataRowHeight, - dataTextStyle, - headingRowColor, - headingRowHeight, - headingTextStyle, - horizontalMargin, - columnSpacing, - dividerThickness, - ); - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) - return true; - if (other.runtimeType != runtimeType) - return false; - return other is DataTableThemeData - && other.decoration == decoration - && other.dataRowColor == dataRowColor - && other.dataRowHeight == dataRowHeight - && other.dataTextStyle == dataTextStyle - && other.headingRowColor == headingRowColor - && other.headingRowHeight == headingRowHeight - && other.headingTextStyle == headingTextStyle - && other.horizontalMargin == horizontalMargin - && other.columnSpacing == columnSpacing - && other.dividerThickness == dividerThickness; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(DiagnosticsProperty('decoration', decoration, defaultValue: null)); - properties.add(DiagnosticsProperty>('dataRowColor', dataRowColor, defaultValue: null)); - properties.add(DoubleProperty('dataRowHeight', dataRowHeight, defaultValue: null)); - properties.add(DiagnosticsProperty('dataTextStyle', dataTextStyle, defaultValue: null)); - properties.add(DiagnosticsProperty>('headingRowColor', headingRowColor, defaultValue: null)); - properties.add(DoubleProperty('headingRowHeight', headingRowHeight, defaultValue: null)); - properties.add(DiagnosticsProperty('headingTextStyle', headingTextStyle, defaultValue: null)); - properties.add(DoubleProperty('horizontalMargin', horizontalMargin, defaultValue: null)); - properties.add(DoubleProperty('columnSpacing', columnSpacing, defaultValue: null)); - properties.add(DoubleProperty('dividerThickness', dividerThickness, defaultValue: null)); - } - - static MaterialStateProperty _lerpProperties(MaterialStateProperty a, MaterialStateProperty b, double t, T Function(T, T, double) lerpFunction ) { - // Avoid creating a _LerpProperties object for a common case. - if (a == null && b == null) - return null; - return _LerpProperties(a, b, t, lerpFunction); - } -} - -class _LerpProperties implements MaterialStateProperty { - const _LerpProperties(this.a, this.b, this.t, this.lerpFunction); - - final MaterialStateProperty a; - final MaterialStateProperty b; - final double t; - final T Function(T, T, double) lerpFunction; - - @override - T resolve(Set states) { - final T resolvedA = a?.resolve(states); - final T resolvedB = b?.resolve(states); - return lerpFunction(resolvedA, resolvedB, t); - } -} - -/// Applies a data table theme to descendant [DataTable] widgets. -/// -/// Descendant widgets obtain the current theme's [DataTableTheme] object using -/// [DataTableTheme.of]. When a widget uses [DataTableTheme.of], it is -/// automatically rebuilt if the theme later changes. -/// -/// A data table theme can be specified as part of the overall Material -/// theme using [ThemeData.dataTableTheme]. -/// -/// See also: -/// -/// * [DataTableThemeData], which describes the actual configuration -/// of a data table theme. -class DataTableTheme extends InheritedWidget { - /// Constructs a data table theme that configures all descendant - /// [DataTable] widgets. - /// - /// The [data] must not be null. - const DataTableTheme({ - Key key, - @required this.data, - Widget child, - }) : assert(data != null), super(key: key, child: child); - - /// The properties used for all descendant [DataTable] widgets. - final DataTableThemeData data; - - /// Returns the configuration [data] from the closest - /// [DataTableTheme] ancestor. If there is no ancestor, it returns - /// [ThemeData.dataTableTheme]. Applications can assume that the - /// returned value will not be null. - /// - /// Typical usage is as follows: - /// - /// ```dart - /// DataTableThemeData theme = DataTableTheme.of(context); - /// ``` - static DataTableThemeData of(BuildContext context) { - final DataTableTheme dataTableTheme = context.dependOnInheritedWidgetOfExactType(); - return dataTableTheme?.data ?? Theme.of(context).dataTableTheme; - } - - @override - bool updateShouldNotify(DataTableTheme oldWidget) => data != oldWidget.data; -} diff --git a/packages/flutter/lib/src/material/paginated_data_table.dart b/packages/flutter/lib/src/material/paginated_data_table.dart index 1269a427be0..a0e99371cfa 100644 --- a/packages/flutter/lib/src/material/paginated_data_table.dart +++ b/packages/flutter/lib/src/material/paginated_data_table.dart @@ -476,7 +476,6 @@ class PaginatedDataTableState extends State { horizontalMargin: widget.horizontalMargin, columnSpacing: widget.columnSpacing, showCheckboxColumn: widget.showCheckboxColumn, - showBottomBorder: true, rows: _getRows(_firstRowIndex, widget.rowsPerPage), ), ), diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index 566193e6eda..389d21f09fa 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -22,7 +22,6 @@ import 'card_theme.dart'; import 'chip_theme.dart'; import 'color_scheme.dart'; import 'colors.dart'; -import 'data_table_theme.dart'; import 'dialog_theme.dart'; import 'divider_theme.dart'; import 'elevated_button_theme.dart'; @@ -284,7 +283,6 @@ class ThemeData with Diagnosticable { ElevatedButtonThemeData elevatedButtonTheme, OutlinedButtonThemeData outlinedButtonTheme, TextSelectionThemeData textSelectionTheme, - DataTableThemeData dataTableTheme, bool fixTextFieldOutlineLabel, bool useTextSelectionTheme, }) { @@ -402,7 +400,6 @@ class ThemeData with Diagnosticable { elevatedButtonTheme ??= const ElevatedButtonThemeData(); outlinedButtonTheme ??= const OutlinedButtonThemeData(); textSelectionTheme ??= const TextSelectionThemeData(); - dataTableTheme ??= const DataTableThemeData(); fixTextFieldOutlineLabel ??= false; useTextSelectionTheme ??= false; @@ -478,7 +475,6 @@ class ThemeData with Diagnosticable { elevatedButtonTheme: elevatedButtonTheme, outlinedButtonTheme: outlinedButtonTheme, textSelectionTheme: textSelectionTheme, - dataTableTheme: dataTableTheme, fixTextFieldOutlineLabel: fixTextFieldOutlineLabel, useTextSelectionTheme: useTextSelectionTheme, ); @@ -565,7 +561,6 @@ class ThemeData with Diagnosticable { @required this.elevatedButtonTheme, @required this.outlinedButtonTheme, @required this.textSelectionTheme, - @required this.dataTableTheme, @required this.fixTextFieldOutlineLabel, @required this.useTextSelectionTheme, }) : assert(visualDensity != null), @@ -634,8 +629,8 @@ class ThemeData with Diagnosticable { assert(textButtonTheme != null), assert(elevatedButtonTheme != null), assert(outlinedButtonTheme != null), + assert(fixTextFieldOutlineLabel != null), assert(textSelectionTheme != null), - assert(dataTableTheme != null), assert(fixTextFieldOutlineLabel != null), assert(useTextSelectionTheme != null); @@ -1112,10 +1107,6 @@ class ThemeData with Diagnosticable { /// A theme for customizing the appearance and layout of [TextField] widgets. final TextSelectionThemeData textSelectionTheme; - /// A theme for customizing the appearance and layout of [DataTable] - /// widgets. - final DataTableThemeData dataTableTheme; - /// A temporary flag to allow apps to opt-in to a /// [small fix](https://github.com/flutter/flutter/issues/54028) for the Y /// coordinate of the floating label in a [TextField] [OutlineInputBorder]. @@ -1215,7 +1206,6 @@ class ThemeData with Diagnosticable { ElevatedButtonThemeData elevatedButtonTheme, OutlinedButtonThemeData outlinedButtonTheme, TextSelectionThemeData textSelectionTheme, - DataTableThemeData dataTableTheme, bool fixTextFieldOutlineLabel, bool useTextSelectionTheme, }) { @@ -1291,7 +1281,6 @@ class ThemeData with Diagnosticable { elevatedButtonTheme: elevatedButtonTheme ?? this.elevatedButtonTheme, outlinedButtonTheme: outlinedButtonTheme ?? this.outlinedButtonTheme, textSelectionTheme: textSelectionTheme ?? this.textSelectionTheme, - dataTableTheme: dataTableTheme ?? this.dataTableTheme, fixTextFieldOutlineLabel: fixTextFieldOutlineLabel ?? this.fixTextFieldOutlineLabel, useTextSelectionTheme: useTextSelectionTheme ?? this.useTextSelectionTheme, ); @@ -1445,7 +1434,6 @@ class ThemeData with Diagnosticable { elevatedButtonTheme: ElevatedButtonThemeData.lerp(a.elevatedButtonTheme, b.elevatedButtonTheme, t), outlinedButtonTheme: OutlinedButtonThemeData.lerp(a.outlinedButtonTheme, b.outlinedButtonTheme, t), textSelectionTheme: TextSelectionThemeData .lerp(a.textSelectionTheme, b.textSelectionTheme, t), - dataTableTheme: DataTableThemeData.lerp(a.dataTableTheme, b.dataTableTheme, t), fixTextFieldOutlineLabel: t < 0.5 ? a.fixTextFieldOutlineLabel : b.fixTextFieldOutlineLabel, useTextSelectionTheme: t < 0.5 ? a.useTextSelectionTheme : b.useTextSelectionTheme, ); @@ -1527,7 +1515,6 @@ class ThemeData with Diagnosticable { && other.elevatedButtonTheme == elevatedButtonTheme && other.outlinedButtonTheme == outlinedButtonTheme && other.textSelectionTheme == textSelectionTheme - && other.dataTableTheme == dataTableTheme && other.fixTextFieldOutlineLabel == fixTextFieldOutlineLabel && other.useTextSelectionTheme == useTextSelectionTheme; } @@ -1608,7 +1595,6 @@ class ThemeData with Diagnosticable { elevatedButtonTheme, outlinedButtonTheme, textSelectionTheme, - dataTableTheme, fixTextFieldOutlineLabel, useTextSelectionTheme, ]; @@ -1687,7 +1673,6 @@ class ThemeData with Diagnosticable { properties.add(DiagnosticsProperty('textButtonTheme', textButtonTheme, defaultValue: defaultData.textButtonTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty('elevatedButtonTheme', elevatedButtonTheme, defaultValue: defaultData.elevatedButtonTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty('outlinedButtonTheme', outlinedButtonTheme, defaultValue: defaultData.outlinedButtonTheme, level: DiagnosticLevel.debug)); - properties.add(DiagnosticsProperty('dataTableTheme', dataTableTheme, defaultValue: defaultData.dataTableTheme, level: DiagnosticLevel.debug)); } } diff --git a/packages/flutter/test/material/data_table_test.dart b/packages/flutter/test/material/data_table_test.dart index 722a8613e19..eee31752fec 100644 --- a/packages/flutter/test/material/data_table_test.dart +++ b/packages/flutter/test/material/data_table_test.dart @@ -177,10 +177,6 @@ void main() { MaterialApp( home: Material( child: DataTable( - headingTextStyle: const TextStyle( - fontSize: 14.0, - letterSpacing: 0.0, // Will overflow if letter spacing is larger than 0.0. - ), columns: [ DataColumn( label: Text('X' * 2000), @@ -199,7 +195,6 @@ void main() { ), ), ); - expect(tester.renderObject(find.byType(Text).first).size.width, greaterThan(800.0)); expect(tester.renderObject(find.byType(Row).first).size.width, greaterThan(800.0)); expect(tester.takeException(), isNull); // column overflows table, but text doesn't overflow cell @@ -697,7 +692,7 @@ void main() { ); // custom first column padding - padding = find.widgetWithText(Padding, 'Frozen yogurt').first; + padding = find.widgetWithText(Padding, 'Frozen yogurt'); cellContent = find.widgetWithText(Align, 'Frozen yogurt'); // DataTable wraps its DataCells in an Align widget expect( tester.getRect(cellContent).left - tester.getRect(padding).left, @@ -957,9 +952,9 @@ void main() { ); Table table = tester.widget(find.byType(Table)); - TableRow tableRow = table.children.last; + TableRow tableRow = table.children.first; BoxDecoration boxDecoration = tableRow.decoration as BoxDecoration; - expect(boxDecoration.border.top.width, 1.0); + expect(boxDecoration.border.bottom.width, 1.0); const double thickness = 4.2; await tester.pumpWidget( @@ -974,58 +969,9 @@ void main() { ), ); table = tester.widget(find.byType(Table)); - tableRow = table.children.last; + tableRow = table.children.first; boxDecoration = tableRow.decoration as BoxDecoration; - expect(boxDecoration.border.top.width, thickness); - }); - - testWidgets('DataTable set show bottom border', (WidgetTester tester) async { - const List columns = [ - DataColumn(label: Text('column1')), - DataColumn(label: Text('column2')), - ]; - - const List cells = [ - DataCell(Text('cell1')), - DataCell(Text('cell2')), - ]; - - const List rows = [ - DataRow(cells: cells), - DataRow(cells: cells), - ]; - - await tester.pumpWidget( - MaterialApp( - home: Material( - child: DataTable( - showBottomBorder: true, - columns: columns, - rows: rows, - ), - ), - ), - ); - - Table table = tester.widget(find.byType(Table)); - TableRow tableRow = table.children.last; - BoxDecoration boxDecoration = tableRow.decoration as BoxDecoration; - expect(boxDecoration.border.bottom.width, 1.0); - - await tester.pumpWidget( - MaterialApp( - home: Material( - child: DataTable( - columns: columns, - rows: rows, - ), - ), - ), - ); - table = tester.widget(find.byType(Table)); - tableRow = table.children.last; - boxDecoration = tableRow.decoration as BoxDecoration; - expect(boxDecoration.border.bottom.width, 0.0); + expect(boxDecoration.border.bottom.width, thickness); }); testWidgets('DataTable column heading cell - with and without sorting', (WidgetTester tester) async { @@ -1279,7 +1225,7 @@ void main() { final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Content1'))); await tester.pump(const Duration(milliseconds: 200)); // splash is well underway final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox; - expect(box, paints..circle(x: 68.0, y: 24.0, color: pressedColor)); + expect(box, paints..circle(x: 64.0, y: 24.0, color: pressedColor)); await gesture.up(); }); } diff --git a/packages/flutter/test/material/data_table_theme_test.dart b/packages/flutter/test/material/data_table_theme_test.dart deleted file mode 100644 index fe409cdadd7..00000000000 --- a/packages/flutter/test/material/data_table_theme_test.dart +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// @dart = 2.8 - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - test('DataTableThemeData copyWith, ==, hashCode basics', () { - expect(const DataTableThemeData(), const DataTableThemeData().copyWith()); - expect(const DataTableThemeData().hashCode, const DataTableThemeData().copyWith().hashCode); - }); - - test('DataTableThemeData defaults', () { - const DataTableThemeData themeData = DataTableThemeData(); - expect(themeData.decoration, null); - expect(themeData.dataRowColor, null); - expect(themeData.dataRowHeight, null); - expect(themeData.dataTextStyle, null); - expect(themeData.headingRowColor, null); - expect(themeData.headingRowHeight, null); - expect(themeData.headingTextStyle, null); - expect(themeData.horizontalMargin, null); - expect(themeData.columnSpacing, null); - expect(themeData.dividerThickness, null); - - const DataTableTheme theme = DataTableTheme(data: DataTableThemeData()); - expect(theme.data.decoration, null); - expect(theme.data.dataRowColor, null); - expect(theme.data.dataRowHeight, null); - expect(theme.data.dataTextStyle, null); - expect(theme.data.headingRowColor, null); - expect(theme.data.headingRowHeight, null); - expect(theme.data.headingTextStyle, null); - expect(theme.data.horizontalMargin, null); - expect(theme.data.columnSpacing, null); - expect(theme.data.dividerThickness, null); - }); - - testWidgets('Default DataTableThemeData debugFillProperties', (WidgetTester tester) async { - final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); - const DataTableThemeData().debugFillProperties(builder); - - final List description = builder.properties - .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info)) - .map((DiagnosticsNode node) => node.toString()) - .toList(); - - expect(description, []); - }); - - testWidgets('DataTableThemeData implements debugFillProperties', (WidgetTester tester) async { - final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); - DataTableThemeData( - decoration: const BoxDecoration(color: Color(0xfffffff0)), - dataRowColor: MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff1), - ), - dataRowHeight: 51.0, - dataTextStyle: const TextStyle(fontSize: 12.0), - headingRowColor: MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff2), - ), - headingRowHeight: 52.0, - headingTextStyle: const TextStyle(fontSize: 14.0), - horizontalMargin: 3.0, - columnSpacing: 4.0, - dividerThickness: 5.0, - ).debugFillProperties(builder); - - final List description = builder.properties - .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info)) - .map((DiagnosticsNode node) => node.toString()) - .toList(); - - expect(description[0], 'decoration: BoxDecoration(color: Color(0xfffffff0))'); - expect(description[1], 'dataRowColor: Instance of \'_MaterialStatePropertyWith\''); - expect(description[2], 'dataRowHeight: 51.0'); - expect(description[3], 'dataTextStyle: TextStyle(inherit: true, size: 12.0)'); - expect(description[4], 'headingRowColor: Instance of \'_MaterialStatePropertyWith\''); - expect(description[5], 'headingRowHeight: 52.0'); - expect(description[6], 'headingTextStyle: TextStyle(inherit: true, size: 14.0)'); - expect(description[7], 'horizontalMargin: 3.0'); - expect(description[8], 'columnSpacing: 4.0'); - expect(description[9], 'dividerThickness: 5.0'); - }); - - testWidgets('DataTable is themeable', (WidgetTester tester) async { - const BoxDecoration decoration = BoxDecoration(color: Color(0xfffffff0)); - final MaterialStateProperty dataRowColor = MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff1), - ); - const double dataRowHeight = 51.0; - const TextStyle dataTextStyle = TextStyle(fontSize: 12.5); - final MaterialStateProperty headingRowColor = MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff2), - ); - const double headingRowHeight = 52.0; - const TextStyle headingTextStyle = TextStyle(fontSize: 14.5); - const double horizontalMargin = 3.0; - const double columnSpacing = 4.0; - const double dividerThickness = 5.0; - - await tester.pumpWidget( - MaterialApp( - theme: ThemeData( - dataTableTheme: DataTableThemeData( - decoration: decoration, - dataRowColor: dataRowColor, - dataRowHeight: dataRowHeight, - dataTextStyle: dataTextStyle, - headingRowColor: headingRowColor, - headingRowHeight: headingRowHeight, - headingTextStyle: headingTextStyle, - horizontalMargin: horizontalMargin, - columnSpacing: columnSpacing, - dividerThickness: dividerThickness, - ), - ), - home: Scaffold( - body: DataTable( - sortColumnIndex: 0, - columns: [ - DataColumn( - label: const Text('A'), - onSort: (int columnIndex, bool ascending) {}, - ), - const DataColumn(label: Text('B')), - ], - rows: const [ - DataRow(cells: [ - DataCell(Text('Data')), - DataCell(Text('Data 2')), - ]), - ], - ), - ), - ), - ); - - final Finder dataTableInkFinder = find.descendant(of: find.byType(DataTable), matching: find.byType(Ink)); - expect(tester.widgetList(dataTableInkFinder).last.decoration, decoration); - - final TextStyle dataRowTextStyle = tester.renderObject(find.text('Data')).text.style; - expect(dataRowTextStyle.fontSize, dataTextStyle.fontSize); - expect(_tableRowBoxDecoration(tester: tester, index: 1).color, dataRowColor.resolve({})); - expect(_tableRowBoxDecoration(tester: tester, index: 1).border.top.width, dividerThickness); - - final Finder dataRowContainer = find.ancestor(of: find.text('Data'), matching: find.byType(Container)); - expect(tester.getSize(dataRowContainer).height, dataRowHeight); - - final TextStyle headingRowTextStyle = tester.renderObject(find.text('A')).text.style; - expect(headingRowTextStyle.fontSize, headingTextStyle.fontSize); - expect(_tableRowBoxDecoration(tester: tester, index: 0).color, headingRowColor.resolve({})); - - final Finder headingRowContainer = find.ancestor(of: find.text('A'), matching: find.byType(Container)); - expect(tester.getSize(headingRowContainer).height, headingRowHeight); - expect(tester.getTopLeft(find.text('A')).dx, horizontalMargin); - expect(tester.getTopLeft(find.text('Data 2')).dx - tester.getTopRight(find.text('Data')).dx, columnSpacing); - }); - - testWidgets('DataTable properties are taken over the theme values', (WidgetTester tester) async { - const BoxDecoration themeDecoration = BoxDecoration(color: Color(0xfffffff1)); - final MaterialStateProperty themeDataRowColor = MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff0), - ); - const double themeDataRowHeight = 50.0; - const TextStyle themeDataTextStyle = TextStyle(fontSize: 11.5); - final MaterialStateProperty themeHeadingRowColor = MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff1), - ); - const double themeHeadingRowHeight = 51.0; - const TextStyle themeHeadingTextStyle = TextStyle(fontSize: 13.5); - const double themeHorizontalMargin = 2.0; - const double themeColumnSpacing = 3.0; - const double themeDividerThickness = 4.0; - - const BoxDecoration decoration = BoxDecoration(color: Color(0xfffffff0)); - final MaterialStateProperty dataRowColor = MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff1), - ); - const double dataRowHeight = 51.0; - const TextStyle dataTextStyle = TextStyle(fontSize: 12.5); - final MaterialStateProperty headingRowColor = MaterialStateProperty.resolveWith( - (Set states) => const Color(0xfffffff2), - ); - const double headingRowHeight = 52.0; - const TextStyle headingTextStyle = TextStyle(fontSize: 14.5); - const double horizontalMargin = 3.0; - const double columnSpacing = 4.0; - const double dividerThickness = 5.0; - await tester.pumpWidget( - MaterialApp( - theme: ThemeData( - dataTableTheme: DataTableThemeData( - decoration: themeDecoration, - dataRowColor: themeDataRowColor, - dataRowHeight: themeDataRowHeight, - dataTextStyle: themeDataTextStyle, - headingRowColor: themeHeadingRowColor, - headingRowHeight: themeHeadingRowHeight, - headingTextStyle: themeHeadingTextStyle, - horizontalMargin: themeHorizontalMargin, - columnSpacing: themeColumnSpacing, - dividerThickness: themeDividerThickness, - ), - ), - home: Scaffold( - body: DataTable( - decoration: decoration, - dataRowColor: dataRowColor, - dataRowHeight: dataRowHeight, - dataTextStyle: dataTextStyle, - headingRowColor: headingRowColor, - headingRowHeight: headingRowHeight, - headingTextStyle: headingTextStyle, - horizontalMargin: horizontalMargin, - columnSpacing: columnSpacing, - dividerThickness: dividerThickness, - sortColumnIndex: 0, - columns: [ - DataColumn( - label: const Text('A'), - onSort: (int columnIndex, bool ascending) {}, - ), - const DataColumn(label: Text('B')), - ], - rows: const [ - DataRow(cells: [ - DataCell(Text('Data')), - DataCell(Text('Data 2')), - ]), - ], - ), - ), - ), - ); - - final Finder dataTableInkFinder = find.descendant(of: find.byType(DataTable), matching: find.byType(Ink)); - expect(tester.widgetList(dataTableInkFinder).last.decoration, decoration); - - final TextStyle dataRowTextStyle = tester.renderObject(find.text('Data')).text.style; - expect(dataRowTextStyle.fontSize, dataTextStyle.fontSize); - expect(_tableRowBoxDecoration(tester: tester, index: 1).color, dataRowColor.resolve({})); - expect(_tableRowBoxDecoration(tester: tester, index: 1).border.top.width, dividerThickness); - - final Finder dataRowContainer = find.ancestor(of: find.text('Data'), matching: find.byType(Container)); - expect(tester.getSize(dataRowContainer).height, dataRowHeight); - - final TextStyle headingRowTextStyle = tester.renderObject(find.text('A')).text.style; - expect(headingRowTextStyle.fontSize, headingTextStyle.fontSize); - expect(_tableRowBoxDecoration(tester: tester, index: 0).color, headingRowColor.resolve({})); - - final Finder headingRowContainer = find.ancestor(of: find.text('A'), matching: find.byType(Container)); - expect(tester.getSize(headingRowContainer).height, headingRowHeight); - expect(tester.getTopLeft(find.text('A')).dx, horizontalMargin); - expect(tester.getTopLeft(find.text('Data 2')).dx - tester.getTopRight(find.text('Data')).dx, columnSpacing); - }); -} - -BoxDecoration _tableRowBoxDecoration({WidgetTester tester, int index}) { - final Table table = tester.widget(find.byType(Table)); - final TableRow tableRow = table.children[index]; - return tableRow.decoration as BoxDecoration; -} diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart index 2bc3bf83cd0..3ebf2dc641a 100644 --- a/packages/flutter/test/material/theme_data_test.dart +++ b/packages/flutter/test/material/theme_data_test.dart @@ -288,7 +288,6 @@ void main() { elevatedButtonTheme: ElevatedButtonThemeData(style: ElevatedButton.styleFrom(primary: Colors.green)), outlinedButtonTheme: OutlinedButtonThemeData(style: OutlinedButton.styleFrom(primary: Colors.blue)), textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.black), - dataTableTheme: const DataTableThemeData(), fixTextFieldOutlineLabel: false, useTextSelectionTheme: false, ); @@ -377,7 +376,6 @@ void main() { elevatedButtonTheme: const ElevatedButtonThemeData(), outlinedButtonTheme: const OutlinedButtonThemeData(), textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.white), - dataTableTheme: const DataTableThemeData(), fixTextFieldOutlineLabel: true, useTextSelectionTheme: true, );