drawer.dart 4.5 KB

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