Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 如何在Flatter中构建自定义图像提供程序?_Flutter - Fatal编程技术网

Flutter 如何在Flatter中构建自定义图像提供程序?

Flutter 如何在Flatter中构建自定义图像提供程序?,flutter,Flutter,我想为自己的图像类编写一个图像提供程序。让我们以下面的小部件作为图像类的示例。这个小部件可以在需要图像实例时使用。现在我正在使用一个小部件,它需要一个图像提供者作为参数。如何构建cusom映像提供程序?(我知道现有的dart软件包,但这里的问题是如何编写自己的图像提供程序) class\u AppImageState扩展状态{ UINT8列出图像数据; 未来下载({iterate=0})异步{ 如果(迭代>=5){ Log.w(“对于${widget.url},迭代次数太多”); 返回; } v

我想为自己的图像类编写一个图像提供程序。让我们以下面的小部件作为图像类的示例。这个小部件可以在需要图像实例时使用。现在我正在使用一个小部件,它需要一个图像提供者作为参数。如何构建cusom映像提供程序?(我知道现有的dart软件包,但这里的问题是如何编写自己的图像提供程序)

class\u AppImageState扩展状态{
UINT8列出图像数据;
未来下载({iterate=0})异步{
如果(迭代>=5){
Log.w(“对于${widget.url},迭代次数太多”);
返回;
}
var反应;
试一试{
var request=wait HttpClient().getUrl(Uri.parse(widget.url));
响应=等待请求。关闭();
}捕获(e){
Log.e(e);
返回计时器(持续时间(秒:迭代+1),()=>下载(迭代:迭代+1));
}
试一试{
if(response!=null&&response.statusCode==200){
Uint8List bytes=等待合并HttpClientResponseBytes(响应);
设置状态(){
imageData=字节;
});
}否则{
返回计时器(持续时间(秒:迭代+1),()=>下载(迭代:迭代+1));
}
}捕获(e){
Log.e(e);
}
}
@凌驾
void didChangeDependencies(){
super.didChangeDependencies();
下载();
}
@凌驾
小部件构建(构建上下文){
返回imageData!=null?Image.memory(imageData):widget.placeholder??Container();
}
}

我遵循
文件图像
编写我自己的图像提供程序,但我并不精通这一点,因此请注意它可能有问题(例如,我不使用gif进行测试),您也可以阅读
文件图像
,它的代码比
网络图像
少,而且易于阅读

class CacheImageProvider extends ImageProvider<CacheImageProvider> {
  final String fileId;//the cache id use to get cache

  CacheImageProvider(this.fileId);

  @override
  ImageStreamCompleter load(CacheImageProvider key, DecoderCallback decode) {
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(decode),
      scale: 1.0,
      debugLabel: fileId,
      informationCollector: () sync* {
        yield ErrorDescription('Path: $fileId');
      },
    );
  }

  Future<Codec> _loadAsync(DecoderCallback decode) async {
    // the DefaultCacheManager() encapsulation, it get cache from local storage.
    final Uint8List bytes = await (await CacheThumbnail.getThumbnail(fileId)).readAsBytes();

    if (bytes.lengthInBytes == 0) {
      // The file may become available later.
      PaintingBinding.instance?.imageCache?.evict(this);
      throw StateError('$fileId is empty and cannot be loaded as an image.');
    }

    return await decode(bytes);
  }

  @override
  Future<CacheImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<CacheImageProvider>(this);
  }
  
  //the custom == and hashCode must be write, because the ImageProvider memory cache use it to identify the same image.
  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) return false;
    bool res = other is CacheImageProvider && other.fileId == fileId;
    return res;
  }

  @override
  int get hashCode => fileId.hashCode;

  @override
  String toString() => '${objectRuntimeType(this, 'CacheImageProvider')}("$fileId")';
}

对于那些正在寻找在Flatter Web图像中添加标题的解决方案的用户, 我根据@nillouise的答案来上课。令人惊讶的是,它是有效的


字符串标记;
字符串库;
类AuthImageProvider扩展了ImageProvider{
最终字符串相对值;
未来resp;
AuthImageProvider(this.relativeUrl){
MAPH={“授权”:“持有者$TOKEN”};
resp=http.client.get(URLBASE+relativeUrl,头:h);
}
@凌驾
ImageStreamCompleter加载(AuthImageProvider密钥,解码){
返回多帧ImageStreamCompleter(
编解码器:加载异步(解码),比例:1.0);
抛出未实现的错误();
}
未来加载异步(解码回调解码)异步{
//DefaultCacheManager()封装,它从本地存储获取缓存。
最终字节=(等待响应).bodyBytes;
if(bytes.lengthInBytes==0){
//该文件可能稍后可用。
PaintingBinding.instance?.imageCache?.execut(此);
抛出状态错误(
“$relativeUrl为空,无法作为图像加载。”);
}
返回等待解码(字节);
}
@凌驾
未来获取密钥(图像配置){
返回同步未来(本);
}
@凌驾
布尔运算符==(对象其他){
if(other.runtimeType!=runtimeType)返回false;
bool res=other是AuthImageProvider&&other.relativeUrl==relativeUrl;
返回res;
}
@凌驾
int get hashCode=>relativeUrl.hashCode;
@凌驾
字符串toString()=>
“${objectRuntimeType(这是,'CacheImageProvider')}($relativeUrl”)”;
}
class CacheImageProvider extends ImageProvider<CacheImageProvider> {
  final String fileId;//the cache id use to get cache

  CacheImageProvider(this.fileId);

  @override
  ImageStreamCompleter load(CacheImageProvider key, DecoderCallback decode) {
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(decode),
      scale: 1.0,
      debugLabel: fileId,
      informationCollector: () sync* {
        yield ErrorDescription('Path: $fileId');
      },
    );
  }

  Future<Codec> _loadAsync(DecoderCallback decode) async {
    // the DefaultCacheManager() encapsulation, it get cache from local storage.
    final Uint8List bytes = await (await CacheThumbnail.getThumbnail(fileId)).readAsBytes();

    if (bytes.lengthInBytes == 0) {
      // The file may become available later.
      PaintingBinding.instance?.imageCache?.evict(this);
      throw StateError('$fileId is empty and cannot be loaded as an image.');
    }

    return await decode(bytes);
  }

  @override
  Future<CacheImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<CacheImageProvider>(this);
  }
  
  //the custom == and hashCode must be write, because the ImageProvider memory cache use it to identify the same image.
  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) return false;
    bool res = other is CacheImageProvider && other.fileId == fileId;
    return res;
  }

  @override
  int get hashCode => fileId.hashCode;

  @override
  String toString() => '${objectRuntimeType(this, 'CacheImageProvider')}("$fileId")';
}
Image(image: CacheImageProvider(_data[index].fileId))