Flutter默认图像未加载

时间:2018-04-29 05:35:33

标签: flutter

新的扑动。从事个人项目。坚持与显示图像相关的小问题。这是我用来显示图像的小部件代码。

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cached_network_image/cached_network_image.dart';

class UserProfile extends StatefulWidget {
  @override
  UserProfileState createState() => new UserProfileState();
}

class UserProfileState extends State<UserProfile> {

  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  Map userDetails = {};
  String profileImgPath;

  @override
  void initState() {
    super.initState();
    getUserDetails();
  }


  Future<Null> getUserDetails() async {
    try {
      final SharedPreferences prefs = await _prefs;
      this.userDetails = json.decode(prefs.getString('user'));

      if (prefs.getString('user') != null) {
        if (this.userDetails['isLoggedIn']) {
          setState(() {
            this.profileImgPath = this.userDetails['profileImg'];
            print('Shared preference userDetailsss : ${this.userDetails}');
          });
        }
      } else {
        print('Shared preference has no data');
      }
    } catch (e) {
      print('Exception caught at getUserDetails method');
      print(e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget profileImage = new Container(
      margin: const EdgeInsets.only(top: 20.0),
      child: new Row(
        children: <Widget>[
        new Expanded(
          child: new Column(
            children: <Widget>[
              new CircleAvatar(
                backgroundImage: (this.profileImgPath == null) ? new AssetImage('images/user-avatar.png') : new CachedNetworkImageProvider(this.profileImgPath),
                radius:50.0,
              )
            ],
          )
        )
        ],
      )
    );

    return new Scaffold(
      appBar: new AppBar(title: new Text("Profile"), backgroundColor: const Color(0xFF009688)),
      body: new ListView(
        children: <Widget>[
          profileImage,
        ],
      ),
    );
  } 
}  

我尝试做的是,只要user-avatar.png没有获得原始图片,就会显示默认的CachedNetworkImageProvider图片。但是,它的表现有点不同。

每当我打开页面时 - 我得到一个空白的蓝色框,然后突然显示来自CachedNetworkImageProvider的原始图像。

enter image description here

无法理解发生了什么。

@Jonah Williams供你参考 - enter image description here

2 个答案:

答案 0 :(得分:4)

CachedNetworkImage无法用于backgroundImage属性,因为它不会扩展ImageProvider。您可以创建如下所述的自定义CircleAvatar以使用CachedNetworkImage包:

class CustomCircleAvatar extends StatelessWidget {

  final int animationDuration;
  final double radius;
  final String imagePath;

  const CustomCircleAvatar({
    Key key, 
    this.animationDuration, 
    this.radius, 
    this.imagePath
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new AnimatedContainer(
      duration: new Duration(
        milliseconds: animationDuration,
      ),
      constraints: new BoxConstraints(
        minHeight: radius,
        maxHeight: radius,
        minWidth: radius,
        maxWidth: radius,
      ),
      child: new ClipOval(
        child: new CachedNetworkImage(
          errorWidget: new Icon(Icons.error),
          fit: BoxFit.cover,
          imageUrl: imagePath,
          placeholder: new CircularProgressIndicator(),
        ),
      ),
    );
  }

}

以及如何使用:

body: new Center(
        child: new CustomCircleAvatar(
          animationDuration: 300,
          radius: 100.0,
          imagePath: 'https://avatars-01.gitter.im/g/u/mi6friend4all_twitter?s=128',
        ),
      ),

也许这不是更好的方式。但是,它有效!

答案 1 :(得分:0)

(我假设CachedNetworkImageProvider实际上是来自this包的CachedNetworkImage)。

这行代码将始终显示第二张图片。

(this.profileImgPath == null)
  ? new AssetImage('images/user-avatar.png')
  : new CachedNetworkImageProvider(this.profileImgPath)

由于profileImagePath不为null,因此永远不会创建AssetImage。即使它是,但一旦它没有缓存的网络图像将在它加载之前替换它。而是使用网络映像的placeholder参数。这将显示您的资产图像,直到加载网络图像。

new CachedNetworkImage(
  placeholder: new AssetImage('images/user-avatar.png'),
  imageUrl: profileImgPath,
)