map_page.dart 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import 'package:application/service/map_watch.dart';
  2. import 'package:common_pub/model/distance.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:get/get.dart';
  5. import '../../../service/api.dart' as api;
  6. import '../../../utils.dart';
  7. import 'package:common_pub/model/position.dart' as m;
  8. import '../../../generated/assets.dart';
  9. import '../../../widget/app_net_image.dart';
  10. typedef MapInfo = api.ToMapSimpleV2;
  11. class MapPageController extends GetxController {
  12. @override
  13. void onInit() {
  14. super.onInit();
  15. mapGetMore();
  16. }
  17. Future<void> mapGetMore() async {
  18. if (isMapGetMoreLoading.value) {
  19. return;
  20. }
  21. isMapGetMoreLoading.value = true;
  22. await tryApi(() async {
  23. final r = await api.ApiService.to.stub.toMapListV2(api.MapListRequestV2()
  24. ..limit = 20
  25. ..offset = mapList.length);
  26. mapList.addAll(r.list);
  27. return;
  28. }, onFinally: () {
  29. isMapGetMoreLoading.value = false;
  30. });
  31. mapListScrollController.addListener(() {
  32. if (mapListScrollController.position.pixels ==
  33. mapListScrollController.position.maxScrollExtent) {
  34. //达到最大滚动位置
  35. mapGetMore();
  36. }
  37. });
  38. }
  39. final mapList = <MapInfo>[].obs;
  40. final isMapGetMoreLoading = false.obs;
  41. final mapListScrollController = ScrollController();
  42. final Rx<m.Position?> position = Rx(null);
  43. }
  44. class MapPage extends StatelessWidget {
  45. const MapPage({super.key});
  46. @override
  47. Widget build(BuildContext context) {
  48. return GetBuilder(
  49. init: MapPageController(),
  50. builder: (c) {
  51. return Container(
  52. width: double.infinity,
  53. height: double.infinity,
  54. margin: const EdgeInsets.all(20),
  55. padding: const EdgeInsets.fromLTRB(58, 28, 58, 28),
  56. decoration: BoxDecoration(
  57. color: Colors.white, borderRadius: BorderRadius.circular(16)),
  58. child: Column(
  59. children: [
  60. Row(
  61. children: [
  62. Container(
  63. width: 14,
  64. height: 14,
  65. decoration: const BoxDecoration(
  66. shape: BoxShape.circle, color: Colors.blue),
  67. ),
  68. const Text('地图列表'),
  69. ],
  70. ),
  71. Expanded(
  72. child: Obx(() => GridView.builder(
  73. itemCount: c.mapList.length,
  74. controller: c.mapListScrollController,
  75. scrollDirection: Axis.horizontal,
  76. gridDelegate:
  77. const SliverGridDelegateWithFixedCrossAxisCount(
  78. //设置列数
  79. crossAxisCount: 2,
  80. //设置横向间距
  81. crossAxisSpacing: 10,
  82. //设置主轴间距
  83. mainAxisSpacing: 10,
  84. childAspectRatio: 1.3),
  85. itemBuilder: (context, i) {
  86. return Obx((){
  87. final data = c.mapList[i];
  88. final id = MapWatchService.instance?.id;
  89. final s = id == MapId(data.mapId);
  90. return GalleryCardWidget(data: data, position: c.position.value, isSelected: s);
  91. }) ;
  92. })))
  93. ],
  94. ),
  95. );
  96. });
  97. }
  98. }
  99. class GalleryCardWidget extends StatelessWidget {
  100. final MapInfo data;
  101. final m.Position? position;
  102. final bool isSelected;
  103. const GalleryCardWidget({
  104. super.key,
  105. required this.data,
  106. required this.position, required this.isSelected});
  107. void onTap(int id) async {
  108. await MapWatchService.setMapById(MapId(id));
  109. }
  110. @override
  111. Widget build(BuildContext context) {
  112. var distance = '--';
  113. if ( data.hasDistance()) {
  114. distance = Distance(m: data.distance).toString();
  115. }
  116. return GestureDetector(
  117. onTap: ()=>onTap(data.mapId),
  118. child: Card(
  119. color: Colors.white,
  120. shadowColor: isSelected? Colors.red: null,
  121. surfaceTintColor: Colors.white,
  122. shape: const RoundedRectangleBorder(
  123. borderRadius: BorderRadius.all(Radius.circular(5.44))),
  124. clipBehavior: Clip.antiAlias,
  125. elevation: isSelected?8:4,
  126. child: Column(
  127. crossAxisAlignment: CrossAxisAlignment.start,
  128. children: [
  129. AspectRatio(aspectRatio: 1.1, child: AppNetImage(netImage: data.image, fit: BoxFit.fitHeight)),
  130. Expanded(
  131. child: Padding(
  132. padding: const EdgeInsets.all(6),
  133. child: Column(
  134. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  135. crossAxisAlignment: CrossAxisAlignment.start,
  136. children: [
  137. Text(
  138. data.name,
  139. style: const TextStyle(
  140. fontSize: 13.5,
  141. fontWeight: FontWeight.w500,
  142. ),
  143. textAlign: TextAlign.start,
  144. maxLines: 1,
  145. overflow: TextOverflow.ellipsis,
  146. ),
  147. Text(
  148. data.description,
  149. style: const TextStyle(
  150. fontSize: 10,
  151. color: Color(0xffc6c6c6),
  152. ),
  153. textAlign: TextAlign.start,
  154. maxLines: 1,
  155. overflow: TextOverflow.ellipsis,
  156. ),
  157. const Spacer(),
  158. DefaultTextStyle(
  159. style: const TextStyle(
  160. color: Colors.black, fontSize: 10),
  161. child: Row(
  162. crossAxisAlignment: CrossAxisAlignment.end,
  163. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  164. children: [
  165. Image.asset(Assets.imagesIcMapScale,
  166. height: 9.6),
  167. Text(' 1:${data.mapScaleNumber}'),
  168. const Spacer(),
  169. Image.asset(Assets.imagesIcLocation,
  170. height: 9.6),
  171. Text(' $distance'),
  172. ],
  173. ))
  174. ],
  175. ))),
  176. ],
  177. ),
  178. ),
  179. );
  180. }
  181. Widget wImage() {
  182. return Stack(
  183. children: [
  184. SizedBox(
  185. height: double.infinity,
  186. child: AppNetImage(netImage: data.image, fit: BoxFit.fitHeight)
  187. ),
  188. ],
  189. );
  190. }
  191. }