drawer.dart 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/consts/styles.dart';
  4. import '../dynamic_drawer.dart';
  5. import 'group.dart';
  6. class VDrawerRadioCellGroup<T, TValue> extends StatefulWidget {
  7. final GlobalKey<ScaffoldState> scaffoldKey;
  8. final String? title;
  9. final List<RadioCellGroupItem<T>> source;
  10. /// 选项文本提取函数
  11. final String Function(T data) labelGetter;
  12. /// 选项值提取函数
  13. final TValue Function(T data) valueGetter;
  14. final VRadioCellGroupCheckChanged<T, TValue>? onChanged;
  15. final ValueChanged<TValue?>? onConfirm;
  16. const VDrawerRadioCellGroup({
  17. super.key,
  18. this.title,
  19. required this.source,
  20. required this.labelGetter,
  21. required this.valueGetter,
  22. this.onChanged,
  23. required this.scaffoldKey,
  24. this.onConfirm,
  25. });
  26. @override
  27. State<StatefulWidget> createState() => _DrawerGroupState<T, TValue>();
  28. }
  29. class _DrawerGroupState<T, TValue>
  30. extends State<VDrawerRadioCellGroup<T, TValue>> {
  31. final ScrollController _scrollController = ScrollController();
  32. @override
  33. Widget build(BuildContext context) {
  34. T? data = widget.source.firstWhereOrNull((e) => e.isChecked)?.data;
  35. TValue? radioValue;
  36. if (data != null) {
  37. radioValue = widget.valueGetter.call(data);
  38. }
  39. return Drawer(
  40. shadowColor: Colors.black.withOpacity(.1),
  41. backgroundColor: Colors.white,
  42. shape: RoundedRectangleBorder(
  43. borderRadius: GlobalStyles.borderRadius,
  44. ),
  45. elevation: 0,
  46. width: 520,
  47. child: Container(
  48. alignment: Alignment.topLeft,
  49. padding: const EdgeInsets.symmetric(vertical: 12),
  50. child: Column(
  51. mainAxisSize: MainAxisSize.min,
  52. children: [
  53. Container(
  54. padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 4),
  55. child: Row(
  56. mainAxisSize: MainAxisSize.max,
  57. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  58. children: [
  59. widget.title != null
  60. ? Text(
  61. widget.title!,
  62. style: const TextStyle(
  63. color: Colors.black,
  64. fontSize: 24,
  65. ),
  66. )
  67. : const SizedBox(width: 1),
  68. IconButton(
  69. onPressed: () {
  70. VDynamicDrawerWrapper.hide(
  71. scaffoldKey: widget.scaffoldKey);
  72. },
  73. icon: Icon(
  74. Icons.close,
  75. color: Colors.grey.shade600,
  76. size: 36,
  77. ),
  78. // style: ButtonStyle(
  79. // shape: MaterialStatePropertyAll(
  80. // RoundedRectangleBorder(
  81. // side: BorderSide(color: Colors.grey.shade600),
  82. // borderRadius: BorderRadius.circular(48),
  83. // ),
  84. // ),
  85. // ),
  86. ),
  87. ],
  88. ),
  89. ),
  90. Expanded(
  91. child: Scrollbar(
  92. thumbVisibility: true,
  93. controller: _scrollController,
  94. child: VRadioCellGroup<T, TValue>(
  95. labelGetter: widget.labelGetter,
  96. controller: _scrollController,
  97. valueGetter: widget.valueGetter,
  98. source: widget.source,
  99. onChanged: (value, isChecked, data, checkedValue) {
  100. radioValue = checkedValue;
  101. widget.onChanged
  102. ?.call(value, isChecked, data, checkedValue);
  103. },
  104. isScrollable: true,
  105. ),
  106. ),
  107. ),
  108. Container(
  109. padding:
  110. const EdgeInsets.symmetric(horizontal: 18).copyWith(top: 8),
  111. alignment: Alignment.center,
  112. child: TextButton(
  113. onPressed: () {
  114. widget.onConfirm?.call(radioValue);
  115. VDynamicDrawerWrapper.hide(scaffoldKey: widget.scaffoldKey);
  116. },
  117. child: Container(
  118. width: double.infinity,
  119. height: 38,
  120. alignment: Alignment.center,
  121. child: const Text(
  122. "确定",
  123. style: TextStyle(fontSize: 20),
  124. ),
  125. ),
  126. ),
  127. ),
  128. ],
  129. ),
  130. ),
  131. );
  132. }
  133. }