Files
food_hub_app/lib/widgets/common/index.dart
2025-11-21 17:15:40 +08:00

216 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:toggle_switch/toggle_switch.dart';
Widget formLabelText({required String labelText, bool isRequired = false}) {
return Text.rich(
TextSpan(
children: [
if (isRequired)
const TextSpan(text: '* ', style: TextStyle(color: Colors.red)),
TextSpan(text: labelText),
],
),
);
}
InputDecoration formInputDecoration({
required String hintText,
IconData? prefixIcon,
}) {
return InputDecoration(
hintText: hintText,
hintStyle: TextStyle(color: Colors.grey),
filled: true,
fillColor: Colors.white,
border: OutlineInputBorder(),
prefixIcon: prefixIcon != null ? Icon(prefixIcon) : null,
);
}
class BuildCard extends StatelessWidget {
final Widget? child;
const BuildCard({super.key, this.child});
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return Container(
decoration: BoxDecoration(
color: colors.surfaceContainer,
borderRadius: BorderRadius.circular(12),
// border: Border.all(color: colors.outline.withAlpha(50), width: 1),
),
padding: const EdgeInsets.all(10),
child: child,
);
}
}
Widget buildEmptyData() {
return Center(
child: Text('暂无数据', style: TextStyle(fontSize: 16, color: Colors.grey)),
);
}
Widget buildToggleSwitch<T extends Enum>({
required BuildContext context,
required T currentTab,
required List<T> tabValues,
required List<String> labels,
required ValueChanged<T> 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]);
}
},
);
}
/// 圆形图标按钮
Widget circleIconButton({
required IconData icon,
required VoidCallback onPressed,
required BuildContext context,
bool? isSmall,
}) {
final double size = isSmall == true ? 24 : 36;
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
fixedSize: Size(size, size),
shape: CircleBorder(),
elevation: 0,
backgroundColor: Theme.of(context).colorScheme.primary,
padding: EdgeInsets.zero,
minimumSize: const Size(0, 0),
),
child: Icon(icon, color: Colors.white),
);
}
Widget buildTag(BuildContext context, String title) {
final colors = Theme.of(context).colorScheme;
return Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
decoration: BoxDecoration(
color: colors.primary.withAlpha(60),
borderRadius: BorderRadius.circular(10),
),
child: Text(title, style: TextStyle(color: colors.primary)),
);
}
/// 确认按钮样式
ButtonStyle primaryButtonStyle() {
return ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.green),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
);
}
/// 取消按钮样式
ButtonStyle cancelButtonStyle() {
return ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.grey),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
);
}
Text buttonText({required String text}) {
return Text(text, style: TextStyle(color: Colors.white));
}
/// 图片错误显示
Widget errorImageContainer(double height) {
return Container(
height: 200,
width: double.infinity,
color: Colors.grey[200],
child: const Icon(Icons.image, color: Colors.grey, size: 30),
);
}
/// 成功消息
void showSuccessToast(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
timeInSecForIosWeb: 1,
backgroundColor: Colors.green,
textColor: Colors.white,
fontSize: 16.0,
);
}
/// 错误消息
void showErrorToast(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
}
Widget buildLoadingIndicator(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return Center(
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(color: Colors.black12, blurRadius: 8, offset: Offset(0, 2)),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(colors.primary),
),
SizedBox(height: 12),
Text(
'加载中',
style: TextStyle(
fontSize: 14,
color: colors.onSurface,
fontWeight: FontWeight.w500,
),
),
],
),
),
);
}