AsperctRaioImage.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'dart:typed_data';
  4. import 'package:flutter/material.dart';
  5. import 'dart:ui' as ui;
  6. typedef AsyncImageWidgetBuilder<T> = Widget Function(
  7. BuildContext context, AsyncSnapshot<T> snapshot, String url);
  8. typedef AsyncImageFileWidgetBuilder<T> = Widget Function(
  9. BuildContext context, AsyncSnapshot<T> snapshot, File file);
  10. typedef AsyncImageMemoryWidgetBuilder<T> = Widget Function(
  11. BuildContext context, AsyncSnapshot<T> snapshot, Uint8List bytes);
  12. enum AsperctRaioImageType { NETWORK, FILE, ASSET, MEMORY }
  13. ///有宽高的Image
  14. class AsperctRaioImage extends StatelessWidget {
  15. String url;
  16. File file;
  17. Uint8List bytes;
  18. final ImageProvider provider;
  19. AsperctRaioImageType type;
  20. AsyncImageWidgetBuilder<ui.Image> builder;
  21. AsyncImageFileWidgetBuilder<ui.Image> filebBuilder;
  22. AsyncImageMemoryWidgetBuilder<ui.Image> memoryBuilder;
  23. AsperctRaioImage.network(url, {Key key, @required this.builder})
  24. : provider = NetworkImage(url),
  25. type = AsperctRaioImageType.NETWORK,
  26. this.url = url;
  27. AsperctRaioImage.file(
  28. file, {
  29. Key key,
  30. @required this.filebBuilder,
  31. }) : provider = FileImage(file),
  32. type = AsperctRaioImageType.FILE,
  33. this.file = file;
  34. AsperctRaioImage.asset(name, {Key key, @required this.builder})
  35. : provider = AssetImage(name),
  36. type = AsperctRaioImageType.ASSET,
  37. this.url = name;
  38. AsperctRaioImage.memory(bytes, {Key key, @required this.memoryBuilder})
  39. : provider = MemoryImage(bytes),
  40. type = AsperctRaioImageType.MEMORY,
  41. this.bytes = bytes;
  42. @override
  43. Widget build(BuildContext context) {
  44. final ImageConfiguration config = createLocalImageConfiguration(context);
  45. final Completer<ui.Image> completer = Completer<ui.Image>();
  46. final ImageStream stream = provider.resolve(config);
  47. ImageStreamListener listener;
  48. listener = ImageStreamListener(
  49. (ImageInfo image, bool sync) {
  50. completer.complete(image.image);
  51. stream.removeListener(listener);
  52. },
  53. onError: (dynamic exception, StackTrace stackTrace) {
  54. completer.complete();
  55. stream.removeListener(listener);
  56. FlutterError.reportError(FlutterErrorDetails(
  57. context: ErrorDescription('image failed to precache'),
  58. library: 'image resource service',
  59. exception: exception,
  60. stack: stackTrace,
  61. silent: true,
  62. ));
  63. },
  64. );
  65. stream.addListener(listener);
  66. return FutureBuilder(
  67. future: completer.future,
  68. builder: (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
  69. if (snapshot.hasData) {
  70. if (type == AsperctRaioImageType.FILE) {
  71. return filebBuilder(context, snapshot, file);
  72. } else if (type == AsperctRaioImageType.MEMORY) {
  73. return memoryBuilder(context, snapshot, bytes);
  74. } else {
  75. return builder(context, snapshot, url);
  76. }
  77. } else {
  78. return Container();
  79. }
  80. });
  81. }
  82. }