action_bar.dart 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import 'package:flutter/material.dart';
  2. import '../../core/theme/app_colors.dart';
  3. import '../../core/theme/app_colors_extension.dart';
  4. /// Pencil Component/ActionBar — 底部操作栏
  5. ///
  6. /// 水平排列三个按钮:重置(可选)、存草稿、提交。
  7. /// 所有按钮圆角22,总高度72,padding 16,gap 12,背景bgCard。
  8. class ActionBar extends StatelessWidget {
  9. final String? leftLabel;
  10. final String? centerLabel;
  11. final String? rightLabel;
  12. final VoidCallback? onLeftTap;
  13. final VoidCallback? onCenterTap;
  14. final VoidCallback? onRightTap;
  15. final bool showLeft;
  16. final bool showCenter;
  17. final bool showRight;
  18. final bool centerTextOnly;
  19. const ActionBar({
  20. super.key,
  21. this.leftLabel,
  22. this.centerLabel,
  23. this.rightLabel,
  24. this.onLeftTap,
  25. this.onCenterTap,
  26. this.onRightTap,
  27. this.showLeft = true,
  28. this.showCenter = true,
  29. this.showRight = true,
  30. this.centerTextOnly = false,
  31. });
  32. @override
  33. Widget build(BuildContext context) {
  34. final colors = Theme.of(context).extension<AppColorsExtension>()!;
  35. return Container(
  36. height: 72,
  37. padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
  38. decoration: BoxDecoration(
  39. color: colors.bgCard,
  40. border: Border(top: BorderSide(color: colors.border, width: 0.5)),
  41. ),
  42. child: Row(
  43. children: _buildButtons(colors),
  44. ),
  45. );
  46. }
  47. List<Widget> _buildButtons(AppColorsExtension colors) {
  48. final buttons = <Widget>[];
  49. void addGap() {
  50. if (buttons.isNotEmpty) buttons.add(const SizedBox(width: 12));
  51. }
  52. if (showLeft && leftLabel != null) {
  53. buttons.add(Expanded(
  54. child: _ActionButton(
  55. label: leftLabel!,
  56. backgroundColor: colors.bgCard,
  57. textColor: colors.textSecondary,
  58. onTap: onLeftTap,
  59. ),
  60. ));
  61. }
  62. if (showCenter && centerLabel != null) {
  63. addGap();
  64. buttons.add(Expanded(
  65. child: _ActionButton(
  66. label: centerLabel!,
  67. backgroundColor: centerTextOnly ? colors.bgCard : colors.primaryLight,
  68. textColor: centerTextOnly ? colors.textSecondary : colors.primary,
  69. onTap: onCenterTap,
  70. ),
  71. ));
  72. }
  73. if (showRight && rightLabel != null) {
  74. addGap();
  75. buttons.add(Expanded(
  76. child: _ActionButton(
  77. label: rightLabel!,
  78. backgroundColor: colors.primary,
  79. textColor: colors.bgCard,
  80. onTap: onRightTap,
  81. ),
  82. ));
  83. }
  84. return buttons;
  85. }
  86. }
  87. class _ActionButton extends StatelessWidget {
  88. final String label;
  89. final Color backgroundColor;
  90. final Color textColor;
  91. final VoidCallback? onTap;
  92. const _ActionButton({
  93. required this.label,
  94. required this.backgroundColor,
  95. required this.textColor,
  96. this.onTap,
  97. });
  98. @override
  99. Widget build(BuildContext context) {
  100. return SizedBox(
  101. height: 40,
  102. child: Material(
  103. color: backgroundColor,
  104. borderRadius: BorderRadius.circular(22),
  105. child: InkWell(
  106. onTap: onTap,
  107. borderRadius: BorderRadius.circular(22),
  108. child: Center(
  109. child: Text(
  110. label,
  111. style: TextStyle(
  112. fontSize: AppFontSizes.body,
  113. fontWeight: FontWeight.w500,
  114. color: textColor,
  115. ),
  116. ),
  117. ),
  118. ),
  119. ),
  120. );
  121. }
  122. }