import 'package:cs_resources/generated/assets.dart'; import 'package:cs_resources/theme/app_colors_theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:plugin_platform/engine/dialog/dialog_engine.dart'; import 'package:widgets/ext/ex_widget.dart'; import 'package:widgets/my_load_image.dart'; import 'package:widgets/my_text_view.dart'; /* * 国家选择控件,用于电话号码区号的选择 */ class CountryCodeSelector extends StatefulWidget { String countryCode; //默认选中新加坡 bool isEnable = true; //是否可用 EdgeInsetsGeometry margin; void Function(String? countryCode) onChanged; //选中的回调 CountryCodeSelector( {Key? key, this.countryCode = "+65", this.isEnable = true, this.margin = const EdgeInsets.only(left: 35, right: 35, top: 5), required this.onChanged}) : super(key: key); @override State createState() { return _CountryCodePickerSelector(); } } class _CountryCodePickerSelector extends State { String? selectedCountryCode; Map? selectedCountryEntity; final List> countries = [ {'code': '+1', 'icon': Assets.authMeiguo}, {'code': '+44', 'icon': Assets.authYinguo}, {'code': '+60', 'icon': Assets.authMalaixiya}, {'code': '+61', 'icon': Assets.authAodaliya}, {'code': '+62', 'icon': Assets.authYindunixiya}, {'code': '+63', 'icon': Assets.authFeilvbing}, {'code': '+65', 'icon': Assets.authXinjiapo}, {'code': '+66', 'icon': Assets.authTaiguo}, {'code': '+86', 'icon': Assets.authZhongguo}, {'code': '+852', 'icon': Assets.authXianggang}, ]; @override void initState() { super.initState(); selectedCountryCode = widget.countryCode.startsWith("+") ? widget.countryCode : "+${widget.countryCode}"; selectedCountryEntity = countries.firstWhere((element) => element['code'] == selectedCountryCode); // 在布局完成之后调用回调 WidgetsBinding.instance.addPostFrameCallback((_) { widget.onChanged.call(selectedCountryCode); }); } @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ MyAssetImage(selectedCountryEntity?['icon'] ?? Assets.authXinjiapo, width: 28, height: 20), MyTextView( selectedCountryEntity?['code'] ?? '+65', marginLeft: 8, marginRight: 10, textColor: context.appColors.authFiledHint, isFontMedium: true, fontSize: 16, ), Opacity( opacity: widget.isEnable ? 1.0 : 0.0, child: MyAssetImage( Assets.baseServiceTriangleDropDown, width: 7, height: 4, color: context.appColors.textBlack, ), ), ], ).onTap(() { if (widget.isEnable) { _showCountryPicker(context); } }); } void _showCountryPicker(BuildContext targetContext) { DialogEngine.showAttach( tag: "CountryCode", targetContext: targetContext, position: DialogPosition.bottom, widget: _AttachCountryDialog( margin: widget.margin, list: countries, onSelected: (item) { setState(() { selectedCountryCode = item['code']; selectedCountryEntity = item; widget.onChanged.call(selectedCountryCode); }); }, ), ); } } //下拉选的弹窗布局 class _AttachCountryDialog extends StatelessWidget { final Function(Map) onSelected; final List> list; EdgeInsetsGeometry margin; // 创建一个构造函数接收 onSelected 回调 _AttachCountryDialog({required this.onSelected, required this.list, required this.margin}); @override Widget build(BuildContext context) { return Container( margin: margin, decoration: BoxDecoration( color: context.appColors.whiteBG, borderRadius: BorderRadius.circular(5.0), // 5个圆角 boxShadow: [ BoxShadow( color: const Color(0xFF656565).withOpacity(0.1), // 阴影颜色,并且设置透明度 offset: const Offset(0, 1.5), // 阴影的偏移量 blurRadius: 2.5, // 模糊半径 spreadRadius: 1.5, // 扩散半径 ), ], ), constraints: const BoxConstraints( maxHeight: 250, // 设置最大高度 maxWidth: 100, ), child: ListView.builder( padding: EdgeInsets.zero, itemCount: list.length, itemBuilder: (context, index) { final item = list[index]; return GestureDetector( onTap: () { onSelected(item); // 点击后调用回调 SmartDialog.dismiss(tag: 'CountryCode'); }, child: Row( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox(width: 15), MyAssetImage(item['icon']!, width: 28, height: 20), MyTextView( item['code']!, marginLeft: 8, marginRight: 10, textColor: context.appColors.textBlack, isFontMedium: true, fontSize: 16, ).expanded(), ], ).marginOnly(top: 7.5, bottom: 7.5), ); }, ), ); } }