country_code_selecter.dart 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import 'package:cs_resources/generated/assets.dart';
  2. import 'package:cs_resources/theme/app_colors_theme.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  5. import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
  6. import 'package:widgets/ext/ex_widget.dart';
  7. import 'package:widgets/my_load_image.dart';
  8. import 'package:widgets/my_text_view.dart';
  9. /*
  10. * 国家选择控件,用于电话号码区号的选择
  11. */
  12. class CountryCodeSelector extends StatefulWidget {
  13. String countryCode; //默认选中新加坡
  14. bool isEnable = true; //是否可用
  15. EdgeInsetsGeometry margin;
  16. void Function(String? countryCode) onChanged; //选中的回调
  17. CountryCodeSelector(
  18. {Key? key, this.countryCode = "+65", this.isEnable = true, this.margin = const EdgeInsets.only(left: 35, right: 35, top: 5), required this.onChanged})
  19. : super(key: key);
  20. @override
  21. State<CountryCodeSelector> createState() {
  22. return _CountryCodePickerSelector();
  23. }
  24. }
  25. class _CountryCodePickerSelector extends State<CountryCodeSelector> {
  26. String? selectedCountryCode;
  27. Map<String, String>? selectedCountryEntity;
  28. final List<Map<String, String>> countries = [
  29. {'code': '+1', 'icon': Assets.authMeiguo},
  30. {'code': '+44', 'icon': Assets.authYinguo},
  31. {'code': '+60', 'icon': Assets.authMalaixiya},
  32. {'code': '+61', 'icon': Assets.authAodaliya},
  33. {'code': '+62', 'icon': Assets.authYindunixiya},
  34. {'code': '+63', 'icon': Assets.authFeilvbing},
  35. {'code': '+65', 'icon': Assets.authXinjiapo},
  36. {'code': '+66', 'icon': Assets.authTaiguo},
  37. {'code': '+86', 'icon': Assets.authZhongguo},
  38. {'code': '+852', 'icon': Assets.authXianggang},
  39. ];
  40. @override
  41. void initState() {
  42. super.initState();
  43. selectedCountryCode = widget.countryCode.startsWith("+") ? widget.countryCode : "+${widget.countryCode}";
  44. selectedCountryEntity = countries.firstWhere((element) => element['code'] == selectedCountryCode);
  45. // 在布局完成之后调用回调
  46. WidgetsBinding.instance.addPostFrameCallback((_) {
  47. widget.onChanged.call(selectedCountryCode);
  48. });
  49. }
  50. @override
  51. Widget build(BuildContext context) {
  52. return Row(
  53. mainAxisSize: MainAxisSize.min,
  54. crossAxisAlignment: CrossAxisAlignment.center,
  55. children: [
  56. MyAssetImage(selectedCountryEntity?['icon'] ?? Assets.authXinjiapo, width: 28, height: 20),
  57. MyTextView(
  58. selectedCountryEntity?['code'] ?? '+65',
  59. marginLeft: 8,
  60. marginRight: 10,
  61. textColor: context.appColors.authFiledHint,
  62. isFontMedium: true,
  63. fontSize: 16,
  64. ),
  65. Opacity(
  66. opacity: widget.isEnable ? 1.0 : 0.0,
  67. child: MyAssetImage(
  68. Assets.baseServiceTriangleDropDown,
  69. width: 7,
  70. height: 4,
  71. color: context.appColors.textBlack,
  72. ),
  73. ),
  74. ],
  75. ).onTap(() {
  76. if (widget.isEnable) {
  77. _showCountryPicker(context);
  78. }
  79. });
  80. }
  81. void _showCountryPicker(BuildContext targetContext) {
  82. DialogEngine.showAttach(
  83. tag: "CountryCode",
  84. targetContext: targetContext,
  85. position: DialogPosition.bottom,
  86. widget: _AttachCountryDialog(
  87. margin: widget.margin,
  88. list: countries,
  89. onSelected: (item) {
  90. setState(() {
  91. selectedCountryCode = item['code'];
  92. selectedCountryEntity = item;
  93. widget.onChanged.call(selectedCountryCode);
  94. });
  95. },
  96. ),
  97. );
  98. }
  99. }
  100. //下拉选的弹窗布局
  101. class _AttachCountryDialog extends StatelessWidget {
  102. final Function(Map<String, String>) onSelected;
  103. final List<Map<String, String>> list;
  104. EdgeInsetsGeometry margin;
  105. // 创建一个构造函数接收 onSelected 回调
  106. _AttachCountryDialog({required this.onSelected, required this.list, required this.margin});
  107. @override
  108. Widget build(BuildContext context) {
  109. return Container(
  110. margin: margin,
  111. decoration: BoxDecoration(
  112. color: context.appColors.whiteBG,
  113. borderRadius: BorderRadius.circular(5.0), // 5个圆角
  114. boxShadow: [
  115. BoxShadow(
  116. color: const Color(0xFF656565).withOpacity(0.1), // 阴影颜色,并且设置透明度
  117. offset: const Offset(0, 1.5), // 阴影的偏移量
  118. blurRadius: 2.5, // 模糊半径
  119. spreadRadius: 1.5, // 扩散半径
  120. ),
  121. ],
  122. ),
  123. constraints: const BoxConstraints(
  124. maxHeight: 250, // 设置最大高度
  125. maxWidth: 100,
  126. ),
  127. child: ListView.builder(
  128. padding: EdgeInsets.zero,
  129. itemCount: list.length,
  130. itemBuilder: (context, index) {
  131. final item = list[index];
  132. return GestureDetector(
  133. onTap: () {
  134. onSelected(item); // 点击后调用回调
  135. SmartDialog.dismiss(tag: 'CountryCode');
  136. },
  137. child: Row(
  138. mainAxisSize: MainAxisSize.max,
  139. crossAxisAlignment: CrossAxisAlignment.center,
  140. children: [
  141. const SizedBox(width: 15),
  142. MyAssetImage(item['icon']!, width: 28, height: 20),
  143. MyTextView(
  144. item['code']!,
  145. marginLeft: 8,
  146. marginRight: 10,
  147. textColor: Colors.black,
  148. isFontMedium: true,
  149. fontSize: 16,
  150. ).expanded(),
  151. ],
  152. ).marginOnly(top: 7.5, bottom: 7.5),
  153. );
  154. },
  155. ),
  156. );
  157. }
  158. }