widget_util.dart 5.0 KB

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