import 'dart:async'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:huixiang/constant.dart'; import 'package:huixiang/data/base_list_data.dart'; import 'package:huixiang/data/vip_card.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/app_util.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/utils/shared_preference.dart'; import 'package:huixiang/view_widget/classic_header.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:huixiang/view_widget/my_footer.dart'; import 'package:huixiang/view_widget/no_data_view.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shimmer/shimmer.dart'; class MineShopPage extends StatefulWidget { @override State createState() { return _MineShopPage(); } } class _MineShopPage extends State with WidgetsBindingObserver { List coupons = []; ApiService? apiService; int current = 1; late RefreshController refreshController; final TextEditingController editingController = TextEditingController(); int optionIndex = 0; bool isKeyBoardShow = false; List hotSearch = []; List historySearch = []; FocusNode _focusNode = FocusNode(); bool hasFocus = true; int priceOrder = 0; int networkStatus = 0; @override void initState() { super.initState(); refreshController = RefreshController(); apiService = ApiService(Dio(), context: context, token: SharedInstance.instance.token); queryVipCard(); _focusNode.addListener(() { setState(() { hasFocus = _focusNode.hasFocus; }); }); } @override void didChangeMetrics() { super.didChangeMetrics(); WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { print("object: ${MediaQuery.of(context).viewInsets.bottom}"); if (MediaQuery.of(context).viewInsets.bottom == 0) { if (isKeyBoardShow) { isKeyBoardShow = false; //关闭键盘 软键盘关闭了, 清除输入控件的焦点, 否则重新进入页面会导致软键盘再弹出问题 FocusScope.of(context).requestFocus(FocusNode()); } } else { isKeyBoardShow = true; } }); }); } ///离开页面记着销毁和清除 @override void dispose() { _focusNode.unfocus(); refreshController.dispose(); super.dispose(); } queryVipCard({bool showLoading = true}) async { try { if (showLoading) S.current.zhengzaijiazai.loading; BaseListData? baseData = await apiService?.vipList({ "keywords": editingController.text, }).catchError((error) { networkStatus = -1; refreshController.refreshFailed(); return BaseListData()..isSuccess = false; }); if (baseData?.isSuccess ?? false) { coupons.clear(); coupons.addAll(baseData!.data ?? []); await loadShopColors(); refreshController.refreshCompleted(); networkStatus = 1; } else { refreshController.refreshFailed(); } } finally { setState(() {}); } } Future loadShopColors() async { await Future.forEach(coupons, (element) async { if ((element.storeList?[0].logo ?? "").isEmpty) { return; } Color? color = await loadShopColor(element.storeList![0].logo!); if (color != null) { element.color = color; } }); setState(() {}); } @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { FocusScope.of(context).requestFocus(FocusNode()); }, child: Scaffold( resizeToAvoidBottomInset: false, appBar: MyAppBar( title: S.of(context).dianpuchongzhi, titleColor: Colors.black, background: Colors.white, leadingColor: Colors.black, ), body: Column( children: [ Container( color: Colors.white, padding: EdgeInsets.only( top: 10.h, bottom: 18, ), child: searchShop(), ), Expanded( child: SmartRefresher( enablePullDown: true, enablePullUp: false, header: MyHeader(), footer: CustomFooter( builder: (context, mode) { return MyFooter(mode); }, ), controller: refreshController, onRefresh: queryVipCard, physics: BouncingScrollPhysics(), child: networkStatus == 0 ? ListView.builder( itemCount: 10, physics: BouncingScrollPhysics(), shrinkWrap: true, itemBuilder: (context, position) { return shopItemSm(); }, ) : ((coupons.length > 0) ? ListView.builder( padding: EdgeInsets.symmetric(vertical: 8), itemBuilder: (context, position) { return GestureDetector( onTap: () { Navigator.of(context).pushNamed( '/router/mine_shop_recharge', arguments: { "id": coupons[position].id, "tenantCode": coupons[position].tenantCode, "storeId": coupons[position].storeList?[0].id }, ).then((value) { queryVipCard(showLoading: false); }); }, child: shopItem(coupons[position]), ); }, itemCount: coupons.length ?? 0, ) : NoDataView( src: "assets/image/icon_empty.webp", isShowBtn: false, text: "还没有会员卡~", fontSize: 16.sp, margin: EdgeInsets.only(top: 120.h), )), ), ) ], ), ), ); } Widget searchShop() { return Container( margin: EdgeInsets.fromLTRB(14.w, 0, 14.w, 0), padding: EdgeInsets.symmetric(vertical: 6.h), decoration: BoxDecoration( color: Color(0xFFF5FAF7), borderRadius: BorderRadius.circular(4), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(12), offset: Offset(0, 3), blurRadius: 14, spreadRadius: 0, ), ], ), child: TextField( textInputAction: TextInputAction.search, onEditingComplete: () { FocusScope.of(context).requestFocus(FocusNode()); queryVipCard(); }, controller: editingController, style: TextStyle( fontSize: 14.sp, ), decoration: InputDecoration( hintText: "搜索联盟会员店", hintStyle: TextStyle( fontSize: 12.sp, color: Color(0xFFB3B3B3), ), isCollapsed: true, prefixIcon: Padding( padding: EdgeInsets.only(left: 5.w, right: 5.w), child: Image.asset( "assets/image/icon_search.webp", width: 16.h, height: 16.h, ), ), prefixIconConstraints: BoxConstraints(), border: InputBorder.none, ), ), ); } int colorByName(String? storeName) { if (storeName?.isNotEmpty ?? false) { return 0xFF32A060; } if (storeName!.contains("百年川椒") || storeName.contains("百年川椒")) { return 0xFFC30D23; } else if (storeName.contains("海峡姐妹") || storeName.contains("海峽姐妹")) { return 0xFFE4C796; } else if (storeName.contains("前进麦味") || storeName.contains("前進麥味")) { return 0xFF265782; } return 0xFF32A060; } Widget shopItem(VipCard vipCard) { return Container( width: double.infinity, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( topLeft: Radius.circular(6), topRight: Radius.circular(6), ), color: vipCard.color, boxShadow: [ BoxShadow( color: vipCard.color.withAlpha(80), offset: Offset(0, -1), blurRadius: 3, spreadRadius: 1, ), ], ), padding: EdgeInsets.only(left: 12.w), margin: EdgeInsets.only(top: 12, left: 14.w, right: 14.w), height: 62.h, child: Row( children: [ MImage( vipCard.storeList?[0].logo ?? "", width: 38, height: 38, fit: BoxFit.cover, radius: BorderRadius.circular(100), errorSrc: "assets/image/default_1.webp", fadeSrc: "assets/image/default_1.webp", ), SizedBox( width: 6, ), Text( vipCard.tenantName ?? "", style: TextStyle( color: Color(0xFFFFFFFF), fontSize: 15.sp, fontWeight: MyFontWeight.medium, ), ), ], ), ), Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( bottomRight: Radius.circular(6), bottomLeft: Radius.circular(6), ), color: Colors.white, boxShadow: [ BoxShadow( color: vipCard.color.withAlpha(10), offset: Offset(0, 2), blurRadius: 5, spreadRadius: 1, ), ], ), padding: EdgeInsets.all(12.h), margin: EdgeInsets.only( bottom: 12, left: 14.w, right: 14.w, ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "店铺余额(元)", style: TextStyle( color: Color(0xFF262626), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), Text( "No.${vipCard.id}", style: TextStyle( color: Color(0xFF262626), fontSize: 12.sp, fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.regular, ), ), ], ), SizedBox( height: 4.h, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Text( "¥${vipCard.balance ?? ""}", style: TextStyle( color: Color(0xFF262626), fontSize: 24.sp, fontWeight: MyFontWeight.bold, ), ), ), Text( "去充值", style: TextStyle( color: Color(0xFF262626), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), SizedBox( width: 2, ), Image.asset( "assets/image/icon_right_z.webp", width: 16, height: 16, color: Color(0xFF262626), ), ], ), ], ), ), ], ), ); } Widget shopItemSm() { return Container( width: double.infinity, margin: EdgeInsets.only( bottom: 12.h, top: 14.h, left: 14.w, right: 14.w, ), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( topLeft: Radius.circular(6), topRight: Radius.circular(6), ), color: Color(0XFFD8D8D8), ), padding: EdgeInsets.only(left: 12.w), height: 62.h, child: Row( children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width: 38.h, height: 38.h, ), ), SizedBox( width: 6, ), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width: 111.w, height: 21.h, ), ), ], ), ), Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( bottomRight: Radius.circular(6), topRight: Radius.circular(6), ), color: Colors.white, ), padding: EdgeInsets.all(12.h), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width: 68.w, height: 17.h, ), ), Spacer(), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width: 120.w, height: 17.h, ), ), ], ), SizedBox( height: 4.h, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width: 98.w, height: 33.h, ), ), Spacer(), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width: 48.w, height: 17.h, ), ), SizedBox( width: 2, ), Image.asset( "assets/image/icon_right_z.webp", width: 16, height: 16, color: Color(0xFF262626), ), ], ), ], ), ), ], ), ); } }