import 'package:flutter/material.dart'; import 'package:flutter_common/widget/dialog_widget.dart'; import 'package:toggle_switch/toggle_switch.dart'; OutlineInputBorder buildFormBoard() { return OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade200), ); } OutlineInputBorder buildFormEnabledBoard() { return OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade200), ); } OutlineInputBorder buildFormFocusedBoard(ColorScheme colors) { return OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: colors.primary), ); } // 底部弹出 void buildModalBottom({ required BuildContext context, required String title, required Widget body, }) { final colors = Theme.of(context).colorScheme; showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (BuildContext context) { return GestureDetector( onTap: () => Navigator.of(context).pop(), child: Container( color: Color.fromRGBO(0, 0, 0, 0.001), child: GestureDetector( onTap: () {}, child: DraggableScrollableSheet( initialChildSize: 0.6, minChildSize: 0.4, maxChildSize: 0.9, builder: (_, controller) { return Container( decoration: BoxDecoration( color: colors.surfaceContainer, border: Border.all( color: colors.outline.withAlpha(50), width: 1, ), borderRadius: BorderRadius.only( topLeft: Radius.circular(24), topRight: Radius.circular(24), ), ), child: buildModalBottomBody(context, title, body), ); }, ), ), ), ); }, ); } Widget buildModalBottomTitle(BuildContext context, String title) { return Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( title, style: TextStyle( fontSize: 20, color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.w700, ), ), ], ), ); } Widget buildModalBottomBody(BuildContext context, String title, Widget body) { return Column( children: [ // 拖拽指示条 Container( margin: EdgeInsets.only(top: 12, bottom: 4), width: 48, height: 4, decoration: BoxDecoration( color: Colors.grey[400], borderRadius: BorderRadius.circular(2), ), ), buildModalBottomTitle(context, title), Divider(height: 1, thickness: 1), Expanded(child: Padding(padding: EdgeInsets.all(12), child: body)), ], ); } // 滑动删除 Widget buildDismissible({ required BuildContext context, required Object id, required Widget child, required VoidCallback onDelete, }) { return Dismissible( key: ValueKey(id), direction: DismissDirection.endToStart, background: _buildDismissBackground(), confirmDismiss: (direction) async { // 这里实现二次确认 return await showConfirmDialog(context, '确定要删除这个项目吗?'); }, onDismissed: (direction) { onDelete(); }, child: child, ); } Widget _buildDismissBackground() { return Container( color: Colors.red, alignment: Alignment.centerRight, padding: const EdgeInsets.only(right: 20), child: const Icon(Icons.delete, color: Colors.white, size: 24), ); } // toggle切换 Widget buildToggleSwitch({ required BuildContext context, required T currentTab, required List tabValues, required List labels, required ValueChanged onTabChanged, }) { final colors = Theme.of(context).colorScheme; return ToggleSwitch( minWidth: 90.0, minHeight: 40.0, initialLabelIndex: tabValues.indexOf(currentTab), totalSwitches: tabValues.length, labels: labels, activeBgColor: [colors.primary], activeFgColor: Colors.white, inactiveBgColor: colors.surfaceContainer, inactiveFgColor: colors.onSurface, cornerRadius: 12.0, customTextStyles: [TextStyle(fontSize: 12, fontWeight: FontWeight.w500)], onToggle: (index) { if (index != null && index < tabValues.length) { onTabChanged(tabValues[index]); } }, ); } ButtonStyle buildSegmentStyle(ColorScheme colors) { return ButtonStyle( side: WidgetStateProperty.all( BorderSide(color: colors.surface, width: 0), ), iconColor: WidgetStateProperty.resolveWith(( Set states, ) { if (states.contains(WidgetState.selected)) { return colors.onPrimary; } return Colors.grey; }), backgroundColor: WidgetStateProperty.resolveWith(( Set states, ) { if (states.contains(WidgetState.selected)) { return colors.primary; } return colors.surfaceContainer; }), foregroundColor: WidgetStateProperty.resolveWith(( Set states, ) { if (states.contains(WidgetState.selected)) { return colors.onPrimary; } return colors.onSurface; }), shape: WidgetStateProperty.all( RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), ); } Widget circleIconButton({ required IconData icon, required VoidCallback onPressed, required BuildContext context, }) { return ElevatedButton( onPressed: onPressed, style: ElevatedButton.styleFrom( shape: CircleBorder(), elevation: 0, backgroundColor: Theme.of(context).colorScheme.primary, padding: EdgeInsets.zero, minimumSize: const Size(0, 0), ), child: Icon(icon, color: Colors.white), ); }