region_pick.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:trackoffical_app/pb.dart' as pb;
  4. import 'package:trackoffical_app/widget/app_top_bar.dart';
  5. import '../styles/theme.dart';
  6. class _Region{
  7. pb.Region region= pb.Region();
  8. bool isSelected = false;
  9. List<_Region> children = [];
  10. }
  11. class RegionPickController extends GetxController {
  12. final List<pb.Region> regions = [];
  13. final found = <pb.Region>[].obs;
  14. final inputName = ''.obs;
  15. final regionLevel1 = <_Region>[].obs;
  16. final regionLevel2 = <_Region>[].obs;
  17. @override
  18. void onInit() {
  19. super.onInit();
  20. for (var one in regions){
  21. if(one.code.contains('0000')){
  22. regionLevel1.add(_Region()
  23. ..region = one);
  24. }
  25. }
  26. }
  27. onInputRegionName(String name) {
  28. final n = name.trim();
  29. inputName.value = n;
  30. found.clear();
  31. if (n.isNotEmpty) {
  32. for (var one in regions) {
  33. if (one.name.contains(name)) {
  34. found.add(one);
  35. }
  36. }
  37. }
  38. }
  39. }
  40. class RegionPick extends GetView<RegionPickController> {
  41. const RegionPick({super.key});
  42. static Future<pb.Region?> show(List<pb.Region> data) async {
  43. return await Get.to(const RegionPick(), binding: BindingsBuilder(() {
  44. var c = RegionPickController();
  45. c.regions.addAll(data);
  46. Get.put(c);
  47. }))!;
  48. }
  49. @override
  50. Widget build(BuildContext context) {
  51. return Scaffold(
  52. appBar: AppTopBar(
  53. title: Container(
  54. decoration: const BoxDecoration(
  55. color: Colors.white,
  56. borderRadius: BorderRadius.all(Radius.circular(20))),
  57. child: TextField(
  58. decoration: const InputDecoration(
  59. hintText: '搜索',
  60. border: InputBorder.none,
  61. contentPadding: EdgeInsets.fromLTRB(14, 5, 70, 5),
  62. isDense: true,
  63. ),
  64. onChanged: (v) => controller.onInputRegionName(v),
  65. maxLines: 1,
  66. ),
  67. ),
  68. automaticallyImplyLeading: true,
  69. ),
  70. body: Obx(() {
  71. if (controller.inputName.value.isEmpty) {
  72. return _normalView(controller);
  73. } else {
  74. return _searchView(controller);
  75. }
  76. }),
  77. );
  78. }
  79. Widget _searchView(RegionPickController c) {
  80. return ListView.builder(
  81. itemCount: c.found.length,
  82. itemBuilder: (BuildContext context, int index) {
  83. return _foundEle(c.found[index]);
  84. });
  85. }
  86. Widget _normalView(RegionPickController c) {
  87. return Row(
  88. children: [
  89. Flexible(child: ListView.builder(
  90. itemCount: c.regionLevel1.length,
  91. itemBuilder: (BuildContext context, int index) {
  92. return _normalEle(c.regionLevel1[index]);
  93. })
  94. ),
  95. const Divider(height: 1),
  96. Flexible(child: ListView.builder(
  97. itemCount: c.regionLevel2.length,
  98. itemBuilder: (BuildContext context, int index) {
  99. return _normalEle(c.regionLevel2[index]);
  100. })
  101. ),
  102. ],
  103. ) ;
  104. }
  105. List<_Region> _getChildren(_Region data){
  106. var rexStr = data.region.code.replaceAll('0000', '[\\d]{4}');
  107. var rex = RegExp(rexStr);
  108. var out = <_Region>[];
  109. for (var one in controller.regions){
  110. if(one.code == data.region.code){
  111. continue;
  112. }
  113. if(one.code.contains(rex)){
  114. out.add(_Region()..region = one);
  115. }
  116. }
  117. return out;
  118. }
  119. Widget _normalEle(_Region data) {
  120. var bkColor = !data.isSelected? Colors.white:Colors.grey;
  121. return GestureDetector(
  122. onTap: () {
  123. var l = _getChildren(data);
  124. if(l.isEmpty){
  125. Get.back(result: data.region);
  126. }else{
  127. controller.regionLevel2.clear();
  128. controller.regionLevel2.addAll(l);
  129. }
  130. },
  131. child: Container(
  132. color: bkColor,
  133. padding: const EdgeInsets.only(left: 12, top: 12, bottom: 12),
  134. width: double.infinity,
  135. child: Text(data.region.name),
  136. ),
  137. );
  138. }
  139. }
  140. Widget _foundEle(pb.Region data) {
  141. return GestureDetector(
  142. onTap: () => Get.back(result: data),
  143. child: Container(
  144. padding: const EdgeInsets.only(left: 12),
  145. height: 48,
  146. width: double.infinity,
  147. child: Column(
  148. children: [
  149. Text(data.name),
  150. const Divider()
  151. ],
  152. ),
  153. ),
  154. );
  155. }
  156. void main() async {
  157. var c = RegionPickController();
  158. var regions = <pb.Region>[pb.Region()..name= '济南'];
  159. c.regions.addAll(regions);
  160. Get.put(c);
  161. runApp(GetMaterialApp(theme: appThemeData(), home: const RegionPick()));
  162. }