util.dart 5.2 KB

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