128 lines
3.3 KiB
Dart
128 lines
3.3 KiB
Dart
import 'package:flutter/material.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,
|
|
);
|
|
}
|
|
|
|
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),
|
|
);
|
|
}
|