widget_util.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import 'dart:async';
  2. import 'package:common_utils/common_utils.dart';
  3. import 'package:flutter/widgets.dart';
  4. /**
  5. * @Author: thl
  6. * @GitHub: https://github.com/Sky24n
  7. * @Email: 863764940@qq.com
  8. * @Email: sky24no@gmail.com
  9. * @Description: Widget Util.
  10. * @Date: 2018/9/10
  11. */
  12. /// Widget Util.
  13. class WidgetUtil {
  14. bool _hasMeasured = false;
  15. double _width;
  16. double _height;
  17. /// Widget rendering listener.
  18. /// Widget渲染监听.
  19. /// context: Widget context.
  20. /// isOnce: true,Continuous monitoring false,Listen only once.
  21. /// onCallBack: Widget Rect CallBack.
  22. void asyncPrepare(
  23. BuildContext context, bool isOnce, ValueChanged<Rect> onCallBack) {
  24. if (_hasMeasured) return;
  25. WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
  26. RenderBox box = context.findRenderObject();
  27. if (box != null && box.semanticBounds != null) {
  28. if (isOnce) _hasMeasured = true;
  29. double width = box.semanticBounds.width;
  30. double height = box.semanticBounds.height;
  31. if (_width != width || _height != height) {
  32. _width = width;
  33. _height = height;
  34. if (onCallBack != null) onCallBack(box.semanticBounds);
  35. }
  36. }
  37. });
  38. }
  39. /// Widget渲染监听.
  40. void asyncPrepares(bool isOnce, ValueChanged<Rect> onCallBack) {
  41. if (_hasMeasured) return;
  42. WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
  43. if (isOnce) _hasMeasured = true;
  44. if (onCallBack != null) onCallBack(null);
  45. });
  46. }
  47. ///get Widget Bounds (width, height, left, top, right, bottom and so on).Widgets must be rendered completely.
  48. ///获取widget Rect
  49. static Rect getWidgetBounds(BuildContext context) {
  50. RenderBox box = context.findRenderObject();
  51. return (box != null && box.semanticBounds != null)
  52. ? box.semanticBounds
  53. : Rect.zero;
  54. }
  55. ///Get the coordinates of the widget on the screen.Widgets must be rendered completely.
  56. ///获取widget在屏幕上的坐标,widget必须渲染完成
  57. static Offset getWidgetLocalToGlobal(BuildContext context) {
  58. RenderBox box = context.findRenderObject();
  59. return box == null ? Offset.zero : box.localToGlobal(Offset.zero);
  60. }
  61. /// get image width height,load error return Rect.zero.(unit px)
  62. /// 获取图片宽高,加载错误情况返回 Rect.zero.(单位 px)
  63. /// image
  64. /// url network
  65. /// local url , package
  66. static Future<Rect> getImageWH(
  67. {Image image, String url, String localUrl, String package}) {
  68. if (ObjectUtil.isEmpty(image) &&
  69. ObjectUtil.isEmpty(url) &&
  70. ObjectUtil.isEmpty(localUrl)) {
  71. return Future.value(Rect.zero);
  72. }
  73. Completer<Rect> completer = Completer<Rect>();
  74. Image img = image != null
  75. ? image
  76. : ((url != null && url.isNotEmpty)
  77. ? Image.network(url)
  78. : Image.asset(localUrl, package: package));
  79. img.image
  80. .resolve(new ImageConfiguration())
  81. .addListener(new ImageStreamListener(
  82. (ImageInfo info, bool _) {
  83. completer.complete(Rect.fromLTWH(0, 0, info.image.width.toDouble(),
  84. info.image.height.toDouble()));
  85. },
  86. onError: (dynamic exception, StackTrace stackTrace) {
  87. completer.completeError(exception, stackTrace);
  88. },
  89. ));
  90. return completer.future;
  91. }
  92. /// get image width height, load error throw exception.(unit px)
  93. /// 获取图片宽高,加载错误会抛出异常.(单位 px)
  94. /// image
  95. /// url network
  96. /// local url (full path/全路径,example:"assets/images/ali_connors.png",""assets/images/3.0x/ali_connors.png"" );
  97. /// package
  98. static Future<Rect> getImageWHE(
  99. {Image image, String url, String localUrl, String package}) {
  100. if (ObjectUtil.isEmpty(image) &&
  101. ObjectUtil.isEmpty(url) &&
  102. ObjectUtil.isEmpty(localUrl)) {
  103. return Future.error("image is null.");
  104. }
  105. Completer<Rect> completer = Completer<Rect>();
  106. Image img = image != null
  107. ? image
  108. : ((url != null && url.isNotEmpty)
  109. ? Image.network(url)
  110. : Image.asset(localUrl, package: package));
  111. img.image
  112. .resolve(new ImageConfiguration())
  113. .addListener(new ImageStreamListener(
  114. (ImageInfo info, bool _) {
  115. completer.complete(Rect.fromLTWH(0, 0, info.image.width.toDouble(),
  116. info.image.height.toDouble()));
  117. },
  118. onError: (dynamic exception, StackTrace stackTrace) {
  119. completer.completeError(exception, stackTrace);
  120. },
  121. ));
  122. return completer.future;
  123. }
  124. }