158 lines
4.3 KiB
Dart
158 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
TextStyle _titleStyle() {
|
|
return TextStyle(fontSize: 16, fontWeight: FontWeight.w600);
|
|
}
|
|
|
|
TextStyle _contentStyle() {
|
|
return TextStyle(fontSize: 16, fontWeight: FontWeight.w500);
|
|
}
|
|
|
|
OutlineInputBorder _border(ColorScheme colors) {
|
|
return OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: colors.onSurface.withAlpha(100), width: 1.5),
|
|
);
|
|
}
|
|
|
|
OutlineInputBorder _enabledBorder(ColorScheme colors) {
|
|
return OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: colors.onSurface.withAlpha(100), width: 1.5),
|
|
);
|
|
}
|
|
|
|
OutlineInputBorder _focusedBorder(ColorScheme colors) {
|
|
return OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: colors.primary, width: 2),
|
|
);
|
|
}
|
|
|
|
EdgeInsetsGeometry _containerPadding() {
|
|
return EdgeInsets.symmetric(horizontal: 16, vertical: 10);
|
|
}
|
|
|
|
Widget buildFormTime({
|
|
required BuildContext context,
|
|
required String name,
|
|
required String title,
|
|
required DateTime? initialValue,
|
|
required ValueChanged<DateTime?> onChanged,
|
|
double width = 100,
|
|
String hintText = '请选择时间',
|
|
}) {
|
|
final colors = Theme.of(context).colorScheme;
|
|
final alphaColor = colors.onSurface.withAlpha(100);
|
|
|
|
return Row(
|
|
children: [
|
|
Container(width: width, child: Text(title, style: _titleStyle())),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: FormBuilderDateTimePicker(
|
|
name: name,
|
|
inputType: InputType.time,
|
|
initialTime: TimeOfDay.now(),
|
|
initialValue: initialValue,
|
|
format: DateFormat.Hm(),
|
|
onChanged: (value) => onChanged(value),
|
|
style: _contentStyle(),
|
|
decoration: InputDecoration(
|
|
hintText: hintText,
|
|
hintStyle: TextStyle(color: alphaColor),
|
|
prefixIcon: Icon(Icons.schedule_rounded, size: 24),
|
|
border: _border(colors),
|
|
enabledBorder: _enabledBorder(colors),
|
|
focusedBorder: _focusedBorder(colors),
|
|
filled: true,
|
|
fillColor: colors.surfaceContainer,
|
|
contentPadding: _containerPadding(),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget buildFormSlider({
|
|
required BuildContext context,
|
|
required String name,
|
|
required String title,
|
|
required String label,
|
|
required double min,
|
|
required double max,
|
|
required double initialValue,
|
|
required int divisions,
|
|
required ValueChanged<double?> onChanged,
|
|
double width = 100,
|
|
}) {
|
|
final colors = Theme.of(context).colorScheme;
|
|
final alphaColor = colors.onSurface.withAlpha(100);
|
|
|
|
return Row(
|
|
children: [
|
|
Container(width: width, child: Text(title, style: _titleStyle())),
|
|
const SizedBox(width: 8),
|
|
|
|
Expanded(
|
|
child: FormBuilderSlider(
|
|
name: name,
|
|
min: min,
|
|
max: max,
|
|
initialValue: initialValue,
|
|
divisions: divisions,
|
|
onChanged: (value) => onChanged(value),
|
|
label: label,
|
|
decoration: const InputDecoration(
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.zero,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget buildFormRadioGroup({
|
|
required BuildContext context,
|
|
required String name,
|
|
required String title,
|
|
required String initialValue,
|
|
required List<String> items,
|
|
required ValueChanged<String?> onChanged,
|
|
double width = 100,
|
|
}) {
|
|
final colors = Theme.of(context).colorScheme;
|
|
final alphaColor = colors.onSurface.withAlpha(100);
|
|
|
|
return Row(
|
|
children: [
|
|
Container(width: width, child: Text(title, style: _titleStyle())),
|
|
const SizedBox(width: 8),
|
|
|
|
Expanded(
|
|
child: FormBuilderRadioGroup<String>(
|
|
name: name,
|
|
options:
|
|
items
|
|
.map(
|
|
(item) =>
|
|
FormBuilderFieldOption(value: item, child: Text(item)),
|
|
)
|
|
.toList(),
|
|
initialValue: initialValue,
|
|
activeColor: colors.primary,
|
|
decoration: const InputDecoration(
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.zero,
|
|
),
|
|
onChanged: (value) => onChanged(value),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|