import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:trackoffical_app/generated/assets.dart'; import 'package:trackoffical_app/model.dart'; import 'package:trackoffical_app/screen.dart'; import 'package:trackoffical_app/service/mock.dart'; import 'package:trackoffical_app/utils.dart'; import 'package:trackoffical_app/view/qr_scan.dart'; import 'package:trackoffical_app/widget/app_dialog.dart'; import '../../widget/app_net_image.dart'; import '../../widget/hard_level.dart'; // import '../activity_list/activity_list_view.dart'; import 'home_controller.dart'; class HomeMapView extends GetView { const HomeMapView({super.key}); @override Widget build(BuildContext context) { return DefaultTabController( initialIndex: 0, length: 2, child: Scaffold( appBar: _AppBar(), body: Padding( padding: const EdgeInsets.all(12), child: TabBarView( children: [_TabMapActivity(), _TabDirect()], )), ), ); } } class _AppBar extends GetView implements PreferredSizeWidget { @override Widget build(BuildContext context) { var theme = Theme.of(context); theme = theme.copyWith( colorScheme: theme.colorScheme.copyWith( surfaceVariant: Colors.transparent, )); return Container( decoration: BoxDecoration( gradient: LinearGradient(colors: [ context.theme.colorScheme.secondary, context.theme.colorScheme.onSecondaryContainer, ]), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.5), spreadRadius: 3, blurRadius: 5, offset: const Offset(0, 2), // changes position of shadow ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: MediaQuery.of(context).padding.top, ), const Spacer(), SizedBox( width: 68.0.wp, height: 40, child: Theme( data: theme, child: TabBar( tabs: const [ Tab(text: '地图/活动'), Tab(text: '直接加入'), ], onTap: (i) { controller.flushGalleryData(); }, labelColor: Colors.white, unselectedLabelColor: Colors.white, labelStyle: const TextStyle( fontSize: 20, fontWeight: FontWeight.w700), unselectedLabelStyle: const TextStyle(fontSize: 14), indicatorColor: Colors.white, ))), ], ), ); } @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); } class _TabMapActivity extends GetView { @override Widget build(BuildContext context) { return Obx(() { final data = controller.mapList; return _dataView(context, data, controller.mapInfoListScrollController); }); } } Widget _dataView(BuildContext context, List data, ScrollController scrollController) { return GridView.builder( itemCount: data.length, controller: scrollController, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( //设置列数 crossAxisCount: 2, //设置横向间距 crossAxisSpacing: 10, //设置主轴间距 mainAxisSpacing: 10, childAspectRatio: 0.66), itemBuilder: (context, i) { return GalleryCardWidget(data: data[i]); }); } class GalleryCardWidget extends GetView { final MapInfo data; const GalleryCardWidget({super.key, required this.data}); void onTap() async { var pin = ''; var isCancel = false; if (data.needPin) { isCancel = true; await Get.dialog(AppDialog( title: const Text('请输入PIN码'), content: SizedBox( width: 50.0.wp, child: TextField( onChanged: (v) { pin = v; }, maxLines: 1, maxLength: 8, style: const TextStyle(color: Colors.white), )), onCancel: () => Get.back(), onConfirm: () { isCancel = false; Get.back(); }, )); } // if (!isCancel) { // Get.to(() => ActivityListView( // mapName: data.name, // mapId: data.id, // pin: pin, // isDirectIn: false, // )); // } } @override Widget build(BuildContext context) { return GestureDetector( onTap: data.isOpen ? onTap : null, child: Card( color: const Color(0xfff2faff), surfaceTintColor: const Color(0xfff2faff), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(5.44))), clipBehavior: Clip.antiAlias, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AspectRatio(aspectRatio: 1, child: wImage()), Expanded( child: Padding( padding: const EdgeInsets.all(6), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( data.name, style: const TextStyle( fontSize: 15.24, fontWeight: FontWeight.w500, ), textAlign: TextAlign.start, maxLines: 1, overflow: TextOverflow.ellipsis, ), Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ // Image.asset(Assets.imagesIcDistanceStraight, height: 10), const Icon( Icons.location_on, size: 15, color: Colors.grey, ), const SizedBox(width: 6), getDistanceText(data), ], ), HardLevel(data.level), ], ), data.isRecommend ? Container( width: 5.56.wp, height: 5.56.wp, decoration: const BoxDecoration( color: Color(0xffffe8d1), shape: BoxShape.circle), alignment: Alignment.center, child: Text( '荐', style: TextStyle( fontSize: 3.33.wp, color: const Color(0xffff870d)), ), ) : const SizedBox() ], ) ], ))), ], ), ), ); } Widget wImage() { return Stack( children: [ SizedBox( height: double.infinity, child: AppNetImage(netImage: data.image, fit: BoxFit.fitHeight)), data.isOpen ? const SizedBox() : Container( width: double.infinity, height: double.infinity, color: Colors.white.withAlpha(178), alignment: Alignment.center, child: const Text( '待开放', style: TextStyle(color: Color(0xffff6203), fontSize: 15.24), ), ) ], ); } Widget getDistanceText(MapInfo data) { return Obx(() { final myPosition = controller.myPosition; var str = '--'; if (myPosition != null) { final p = data.position; str = p.distance(myPosition).toString(); } return Text(str, style: const TextStyle(color: Colors.grey)); }); } } class _TabDirect extends GetView { @override Widget build(BuildContext context) { return Column( children: [ SizedBox( height: 50.0.wp, child: Center( child: _pinInput())), _divider(), Expanded( flex: 100, child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ GestureDetector( onTap: () async { final pin = await QRScan.scan(); if (pin != null) { _submit(pin); } }, child: Image.asset( Assets.imagesIcQrCode, height: 19.52.wp, ), ), SizedBox( height: 4.68.wp, ), const Text('点击扫码加入') ], )), ) ], ); } Widget _pinInput(){ final con = TextEditingController(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 13.3.wp, child: Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 52.0.wp, child: TextField( controller: con, decoration: const InputDecoration( border: OutlineInputBorder(), ), maxLines: 1, ), ), SizedBox(width: 1.39.wp), SizedBox( height: double.infinity, child: FilledButton( style: FilledButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(1.67.wp)), ), onPressed: () { _submit(con.text); }, child: Text( '加入', style: TextStyle(fontSize: 5.0.wp), ), ), ) ], ), ), SizedBox(height: 1.0.wp), Text('请输入PIN码加入活动', style: TextStyle(fontSize: 4.4.wp, color: Colors.grey),) ], ); } Widget _divider(){ return SizedBox(width: 76.0.wp, child: Row( children: [ const Expanded(child: Divider()), SizedBox(width: 3.0.wp), const Text('或'), SizedBox(width: 3.0.wp), const Expanded(child: Divider()), ], )) ; } void _submit(String pin) { tryCatchApi(() async { // Get.to(() => ActivityListView( // mapName: '', // mapId: 0, // pin: pin, // isDirectIn: true, // )); }); } } void main() { Mock.initServices(); Get.put(HomeController()); runPreview(const HomeMapView()); }