elevation_screen.dart 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Copyright 2021 The Flutter team. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. import 'package:flutter/material.dart';
  5. class ElevationScreen extends StatelessWidget {
  6. const ElevationScreen({super.key});
  7. @override
  8. Widget build(BuildContext context) {
  9. Color shadowColor = Theme.of(context).colorScheme.shadow;
  10. Color surfaceTint = Theme.of(context).colorScheme.primary;
  11. return Expanded(
  12. child: CustomScrollView(
  13. slivers: [
  14. SliverToBoxAdapter(
  15. child: Padding(
  16. padding: const EdgeInsets.fromLTRB(16.0, 20, 16.0, 0),
  17. child: Text(
  18. 'Surface Tint Color Only',
  19. style: Theme.of(context).textTheme.titleLarge,
  20. ),
  21. ),
  22. ),
  23. ElevationGrid(surfaceTintColor: surfaceTint),
  24. SliverList(
  25. delegate: SliverChildListDelegate(<Widget>[
  26. const SizedBox(height: 10),
  27. Padding(
  28. padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
  29. child: Text(
  30. 'Surface Tint Color and Shadow Color',
  31. style: Theme.of(context).textTheme.titleLarge,
  32. ),
  33. ),
  34. ]),
  35. ),
  36. ElevationGrid(
  37. shadowColor: shadowColor,
  38. surfaceTintColor: surfaceTint,
  39. ),
  40. SliverList(
  41. delegate: SliverChildListDelegate(<Widget>[
  42. const SizedBox(height: 10),
  43. Padding(
  44. padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
  45. child: Text(
  46. 'Shadow Color Only',
  47. style: Theme.of(context).textTheme.titleLarge,
  48. ),
  49. ),
  50. ]),
  51. ),
  52. ElevationGrid(shadowColor: shadowColor),
  53. ],
  54. ),
  55. );
  56. }
  57. }
  58. const double narrowScreenWidthThreshold = 450;
  59. class ElevationGrid extends StatelessWidget {
  60. const ElevationGrid({super.key, this.shadowColor, this.surfaceTintColor});
  61. final Color? shadowColor;
  62. final Color? surfaceTintColor;
  63. List<ElevationCard> elevationCards(
  64. Color? shadowColor, Color? surfaceTintColor) {
  65. return elevations
  66. .map(
  67. (elevationInfo) => ElevationCard(
  68. info: elevationInfo,
  69. shadowColor: shadowColor,
  70. surfaceTint: surfaceTintColor,
  71. ),
  72. )
  73. .toList();
  74. }
  75. @override
  76. Widget build(BuildContext context) {
  77. return SliverPadding(
  78. padding: const EdgeInsets.all(8),
  79. sliver: SliverLayoutBuilder(builder: (context, constraints) {
  80. if (constraints.crossAxisExtent < narrowScreenWidthThreshold) {
  81. return SliverGrid.count(
  82. crossAxisCount: 3,
  83. children: elevationCards(shadowColor, surfaceTintColor),
  84. );
  85. } else {
  86. return SliverGrid.count(
  87. crossAxisCount: 6,
  88. children: elevationCards(shadowColor, surfaceTintColor),
  89. );
  90. }
  91. }),
  92. );
  93. }
  94. }
  95. class ElevationCard extends StatefulWidget {
  96. const ElevationCard(
  97. {super.key, required this.info, this.shadowColor, this.surfaceTint});
  98. final ElevationInfo info;
  99. final Color? shadowColor;
  100. final Color? surfaceTint;
  101. @override
  102. State<ElevationCard> createState() => _ElevationCardState();
  103. }
  104. class _ElevationCardState extends State<ElevationCard> {
  105. late double _elevation;
  106. @override
  107. void initState() {
  108. super.initState();
  109. _elevation = widget.info.elevation;
  110. }
  111. @override
  112. Widget build(BuildContext context) {
  113. const BorderRadius borderRadius = BorderRadius.all(Radius.circular(4.0));
  114. final Color color = Theme.of(context).colorScheme.surface;
  115. return Padding(
  116. padding: const EdgeInsets.all(8.0),
  117. child: Material(
  118. borderRadius: borderRadius,
  119. elevation: _elevation,
  120. color: color,
  121. shadowColor: widget.shadowColor,
  122. surfaceTintColor: widget.surfaceTint,
  123. type: MaterialType.card,
  124. child: Padding(
  125. padding: const EdgeInsets.all(8.0),
  126. child: Column(
  127. crossAxisAlignment: CrossAxisAlignment.start,
  128. children: <Widget>[
  129. Text(
  130. 'Level ${widget.info.level}',
  131. style: Theme.of(context).textTheme.labelMedium,
  132. ),
  133. Text(
  134. '${widget.info.level.toInt()} dp',
  135. style: Theme.of(context).textTheme.labelMedium,
  136. ),
  137. if (widget.surfaceTint != null)
  138. Expanded(
  139. child: Align(
  140. alignment: Alignment.bottomRight,
  141. child: Text(
  142. '${widget.info.overlayPercent}%',
  143. style: Theme.of(context).textTheme.bodySmall,
  144. ),
  145. ),
  146. ),
  147. ],
  148. ),
  149. ),
  150. ),
  151. );
  152. }
  153. }
  154. class ElevationInfo {
  155. const ElevationInfo(this.level, this.elevation, this.overlayPercent);
  156. final int level;
  157. final double elevation;
  158. final int overlayPercent;
  159. }
  160. const List<ElevationInfo> elevations = <ElevationInfo>[
  161. ElevationInfo(0, 0.0, 0),
  162. ElevationInfo(1, 1.0, 5),
  163. ElevationInfo(2, 3.0, 8),
  164. ElevationInfo(3, 6.0, 11),
  165. ElevationInfo(4, 8.0, 12),
  166. ElevationInfo(5, 12.0, 14),
  167. ];