util.dart 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'dart:math';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/widgets.dart';
  7. import 'log_utils.dart';
  8. import 'package:intl/intl.dart';
  9. class Utils {
  10. /// 是否字符串为空
  11. static bool isEmpty(String? value) {
  12. if (value == null) {
  13. return true;
  14. }
  15. return value.isEmpty || value == 'null';
  16. }
  17. /// 字符串是否不为空
  18. static bool isNotEmpty(String? value) {
  19. return !isEmpty(value);
  20. }
  21. /// 判断邮箱
  22. static isEmail(dynamic value, {String? country = "sg"}) {
  23. switch (country) {
  24. case "sg":
  25. RegExp regExp = RegExp(r"^\w{1,}(.\w+)*@[A-z0-9]+(\.[A-z]{2,6}){1,2}$");
  26. if (regExp.hasMatch(value.toString())) {
  27. return true;
  28. } else {
  29. return false;
  30. }
  31. default:
  32. return false;
  33. }
  34. }
  35. /// 判断中国的11位手机号码
  36. static bool isChinaPhoneNumber(dynamic value) {
  37. RegExp regExp = RegExp(r"^1\d{10}$"); // 匹配以1开头的11位数字
  38. if (regExp.hasMatch(value.toString())) {
  39. return true;
  40. } else {
  41. return false;
  42. }
  43. }
  44. /// 全局的路由key
  45. static final navKey = GlobalKey<NavigatorState>();
  46. /// 全局的组件key
  47. static final widgetKey = GlobalKey<State>();
  48. //页面缓存key
  49. static dynamic pageStorageKey(dynamic keyname) {
  50. return PageStorageKey<dynamic>(keyname);
  51. }
  52. /// 关闭软键盘
  53. static void hideKeyboard(BuildContext context) {
  54. FocusScopeNode currentFocus = FocusScope.of(context);
  55. if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
  56. FocusManager.instance.primaryFocus!.unfocus();
  57. }
  58. }
  59. /// map 转 json 字符串
  60. static String encodeMap(Map<String, dynamic> mapData) {
  61. return json.encode(mapData);
  62. }
  63. /// json 字符串转 map
  64. static Map<String, dynamic> decodeJson(jsonStr) {
  65. return json.decode(jsonStr.toString());
  66. }
  67. /// 判断颜色是否是暗色还是亮色
  68. static num getComputeLuminance(Color color) {
  69. return color.computeLuminance();
  70. }
  71. /// 随机获取指定返回内的数值
  72. static int getRandomRangeInt(int min, int max) {
  73. final Random random = Random();
  74. return min + random.nextInt(max + 1 - min);
  75. }
  76. /// 无参数的防抖函数
  77. static VoidCallback debounce(
  78. VoidCallback func, [
  79. Duration delay = const Duration(milliseconds: 400),
  80. ]) {
  81. late Timer timer;
  82. return () {
  83. if (timer.isActive == true) {
  84. timer.cancel();
  85. }
  86. timer = Timer(delay, () {
  87. func.call();
  88. });
  89. };
  90. }
  91. /// 带参数的防抖函数
  92. static Function debounceArg<T>(
  93. Function func, [
  94. Duration delay = const Duration(milliseconds: 2000),
  95. ]) {
  96. late Timer timer;
  97. return (T arg) {
  98. if (timer.isActive == true) {
  99. timer.cancel();
  100. }
  101. timer = Timer(delay, () {
  102. func.call(arg);
  103. });
  104. };
  105. }
  106. /// 将时间转化为 多久之前
  107. static String getTimeAgo(String? dateTimeStr,{ String? format}) {
  108. if (dateTimeStr == null || dateTimeStr.isEmpty) {
  109. return 'Unknown time'; // 或者返回其他默认值
  110. }
  111. DateTime? dateTime;
  112. try {
  113. if (format == null){
  114. dateTime = DateTime.parse(dateTimeStr);
  115. }else{
  116. //如果有指定的格式可以按照这个格式来解析时间
  117. DateFormat dateFormat = DateFormat(format, 'en_US');
  118. dateTime = dateFormat.parse(dateTimeStr);
  119. Log.d("dateTime:$dateTime");
  120. }
  121. } catch (e) {
  122. Log.e("Error parsing date: $e");
  123. return 'Invalid date format'; // 或者返回其他默认值
  124. }
  125. if (dateTime == null) {
  126. return 'Unknown time'; // 或者返回其他默认值
  127. }
  128. final now = DateTime.now();
  129. final difference = now.difference(dateTime);
  130. if (difference.inHours < 1) {
  131. return "${difference.inMinutes} minutes ago";
  132. } else if (difference.inHours < 24) {
  133. return "${difference.inHours} hours ago";
  134. } else if (difference.inDays < 7) {
  135. return "${difference.inDays} days ago";
  136. } else if (difference.inDays < 30) {
  137. return "${(difference.inDays / 7).floor()} weeks ago";
  138. } else if (difference.inDays < 365) {
  139. return "${(difference.inDays / 30).floor()} months ago";
  140. } else {
  141. return "${(difference.inDays / 365).floor()} years ago";
  142. }
  143. }
  144. /// 从 Url 中找到对应的宽高
  145. static List<double>? extractWidthHeight(String? url) {
  146. if (isEmpty(url)) return null;
  147. // 使用正则表达式来查找形如 "宽x高" 的部分
  148. final RegExp regex = RegExp(r'-(\d+)x(\d+)\.');
  149. final matches = regex.allMatches(url!);
  150. if (matches.isNotEmpty) {
  151. // 获取最后一个匹配项
  152. final lastMatch = matches.last;
  153. final width = double.parse(lastMatch.group(1)!);
  154. final height = double.parse(lastMatch.group(2)!);
  155. return [width, height]; // 返回宽高列表
  156. }
  157. return null; // 未找到宽高
  158. }
  159. /// 将字符串的前三位和后两位显示,中间用 * 替代。
  160. static String maskString(String input) {
  161. // 检查字符串长度
  162. if (input.length <= 5) {
  163. // 如果字符串长度小于等于5,直接返回原字符串
  164. return input;
  165. }
  166. // 获取前三位和后两位
  167. String start = input.substring(0, 3);
  168. String end = input.substring(input.length - 2);
  169. // 计算中间需要的 * 的数量
  170. int asterisksCount = input.length - 5; // 计算需要的 * 的数量
  171. String asterisks = '*' * asterisksCount; // 创建 * 字符串
  172. // 拼接成新的字符串
  173. return '$start$asterisks$end';
  174. }
  175. }