mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

Also: - minor improvements to documentation - wrap one of our test error messages in a manner more consistent with other messages
105 lines
3.4 KiB
Dart
105 lines
3.4 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'dart:ui' as ui;
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
@immutable
|
|
class CustomNetworkImage extends ImageProvider<Uri> {
|
|
const CustomNetworkImage(this.url);
|
|
|
|
final String url;
|
|
|
|
@override
|
|
Future<Uri> obtainKey(ImageConfiguration configuration) {
|
|
final Uri result = Uri.parse(url).replace(
|
|
queryParameters: <String, String>{
|
|
'dpr': '${configuration.devicePixelRatio}',
|
|
'locale': '${configuration.locale?.toLanguageTag()}',
|
|
'platform': '${configuration.platform?.name}',
|
|
'width': '${configuration.size?.width}',
|
|
'height': '${configuration.size?.height}',
|
|
'bidi': '${configuration.textDirection?.name}',
|
|
},
|
|
);
|
|
return SynchronousFuture<Uri>(result);
|
|
}
|
|
|
|
static HttpClient get _httpClient {
|
|
HttpClient? client;
|
|
assert(() {
|
|
if (debugNetworkImageHttpClientProvider != null) {
|
|
client = debugNetworkImageHttpClientProvider!();
|
|
}
|
|
return true;
|
|
}());
|
|
return client ?? HttpClient()..autoUncompress = false;
|
|
}
|
|
|
|
@override
|
|
ImageStreamCompleter loadImage(Uri key, ImageDecoderCallback decode) {
|
|
final StreamController<ImageChunkEvent> chunkEvents = StreamController<ImageChunkEvent>();
|
|
debugPrint('Fetching "$key"...');
|
|
return MultiFrameImageStreamCompleter(
|
|
codec: _httpClient.getUrl(key)
|
|
.then<HttpClientResponse>((HttpClientRequest request) => request.close())
|
|
.then<Uint8List>((HttpClientResponse response) {
|
|
return consolidateHttpClientResponseBytes(
|
|
response,
|
|
onBytesReceived: (int cumulative, int? total) {
|
|
chunkEvents.add(ImageChunkEvent(
|
|
cumulativeBytesLoaded: cumulative,
|
|
expectedTotalBytes: total,
|
|
));
|
|
},
|
|
);
|
|
})
|
|
.catchError((Object e, StackTrace stack) {
|
|
scheduleMicrotask(() {
|
|
PaintingBinding.instance.imageCache.evict(key);
|
|
});
|
|
return Future<Uint8List>.error(e, stack);
|
|
})
|
|
.whenComplete(chunkEvents.close)
|
|
.then<ui.ImmutableBuffer>(ui.ImmutableBuffer.fromUint8List)
|
|
.then<ui.Codec>(decode),
|
|
chunkEvents: chunkEvents.stream,
|
|
scale: 1.0,
|
|
debugLabel: '"key"',
|
|
informationCollector: () => <DiagnosticsNode>[
|
|
DiagnosticsProperty<ImageProvider>('Image provider', this),
|
|
DiagnosticsProperty<Uri>('URL', key),
|
|
],
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() => '${objectRuntimeType(this, 'CustomNetworkImage')}("$url")';
|
|
}
|
|
|
|
void main() => runApp(const ExampleApp());
|
|
|
|
class ExampleApp extends StatelessWidget {
|
|
const ExampleApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
home: LayoutBuilder(
|
|
builder: (BuildContext context, BoxConstraints constraints) {
|
|
return Image(
|
|
image: const CustomNetworkImage('https://flutter.github.io/assets-for-api-docs/assets/widgets/flamingos.jpg'),
|
|
width: constraints.hasBoundedWidth ? constraints.maxWidth : null,
|
|
height: constraints.hasBoundedHeight ? constraints.maxHeight : null,
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|