阅读 62

【Flutter 踩坑】屏幕宽度测量错误导致image不展示

开始玩flutter,想简单的做个图片列表。图片的宽度为match屏幕。

首先度娘告诉我,获取屏幕的宽度的方法如下:

MediaQuery.of(context).size.width
复制代码

由于flutter不能想Android原生那样,直接设置match_parent。所以只能设置widgetwidthheight

下面先粘出自己摸索出来的代码:

//加载网络图片
new Image.network(
 'your imgeurl',
 width: MediaQuery.of(context).size.width,
 height:200.0,
 fit : BoxFit.fill
 )
复制代码

完整的代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_app/ComicBean.dart';
import 'ToastUtils.dart';



const  api="https://manga.bilibili.com/twirp/comic.v1.Comic/HomePage?device=h5&platform=h5";
class HomeList extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState

    var list = [
      new ComicBean("钻石王牌 act2", "最新上线",
          "https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1555383014&di=b62daefbde9a49eec1abd5b111b39279&src=http://img3.duitang.com/uploads/blog/201504/04/20150404171530_FCfLe.thumb.700_0.jpeg"),
      new ComicBean("皇帝的独生女", "275",
          "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555393097026&di=97a2a368fffa0adb6d4c1f999bb20fc2&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201511%2F06%2F20151106224057_FQBj2.thumb.700_0.png"),
      new ComicBean("吾皇巴扎黑", "第151话",
          "https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1555383014&di=b62daefbde9a49eec1abd5b111b39279&src=http://img3.duitang.com/uploads/blog/201504/04/20150404171530_FCfLe.thumb.700_0.jpeg"),
    ];
    return new _HomeListState(list);
  }
}

class _HomeListState extends State<HomeList> {
  _HomeListState(this.listData);

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  var listData = new List<ComicBean>();

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Container(
      child: new ListView.builder(
          itemCount: listData.length,
          itemBuilder: (BuildContext context, int position) {
            return getItem(context, listData[position]);
          }),
    );
  }
//生产没个item
  getItem(BuildContext context, ComicBean subject) {
    var column = Container(
      margin: EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          ClipRRect(
            borderRadius: BorderRadius.circular(4.0),
            //注意此处
            child: new Image.network(
              subject.img,
              width: MediaQuery.of(context).size.width,//设置宽度,问题的关键
              height: 200.0,
              fit: BoxFit.fill,
            ),
          ),
          Container(
            padding: EdgeInsets.only(top: 5.0),
            child: Text(
              subject.title,
              style: TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: 20.0,
              ),
            ),
          ),
          Container(
            padding: EdgeInsets.only(top: 3.0),
            child: Text(
              subject.sub_title,
              style: TextStyle(
                color: Colors.black38,
                fontSize: 14.0,
              ),
            ),
          ),
        ],
      ),
    );
    return new GestureDetector(
      onTap: () {
        showLongToast(subject.title + "被点击了!");
      },
      child: Card(
        child: column,
        shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(4.0))),
      ),
    );
  }
}
复制代码

ok将上面自定义的list widget放到任意的容器中。开始debug,发现图片已经完全显示出来了,then打release包,再次在真机上面运行。发现第一个item的图片不会显示出来。但是debug是可以的。

debug--> ok

release--> no 这个时候,按照我的脑回路应该是混淆问题了,但是Android 项目下的build.gradle并没有开启混淆。是不是一定要开启混淆,然后去了官方git下把混淆文件配置好之后。ok应该没问题了吧。##¥¥%% 在一段激烈的命令行下,成功的编译出了release的混淆apk,包体积是小了点,然后运行在真机上面,我* 还是不显示。

首先看了console 没有任何报错信息,难道是官方的Image.network 有问题,好的,感觉抓到了救命稻草,度娘告诉我还有个第三方库的CachedNetworkImage。果断集成一下,应该好了吧,继续重复前面的工作,再次运行。我¥¥%¥#%#……%……%#¥%#,还是不行。

那就是我widegt用的方式不对?但是和度娘找出的demo基本用法都一样啊,于是我找了一个类似的demo在自己的项目中试了一下。ok,人家的完全没有问题,然后一行行对比,最终好想只有width我给的不是一个确定的值。于是抱着试一试的态度,给其设置了固定的宽度

new CachedNetworkImage(
              placeholder: (context,url)=> Image.asset('images/placeholder.png'),
              imageUrl: subject.imageUrl,
              width: 150.0,
              height: 200.0,
              fit: BoxFit.fill,
            )
复制代码

依然是重复前面的操作,运行OK了。竟然OK了。为啥呢?难道是MediaQuery.of(context).size.width这个方法在搞我?后来冷静的想了想,这个宽度的获取时机是不正确的,需要提前的去获取这个宽度。因此对上面的代码进行修改:

...
 var width=0;
 @override
  Widget build(BuildContext context) {
    // TODO: implement build
    //在生成item之前先获取屏幕的宽度
    width= MediaQuery.of(context).size.width;
    return new Container(
      child: new ListView.builder(
          itemCount: listData.length,
          itemBuilder: (BuildContext context, int position) {
            return getItem(context, listData[position]);
          }),
    );
  }
  
 ···
 
 new CachedNetworkImage(
              placeholder: (context,url)=> Image.asset('images/placeholder.png'),
              imageUrl: subject.imageUrl,
              width: width,//换成提前获取的宽度
              height: 200.0,
              fit: BoxFit.fill,
            )
            ···
复制代码
关注下面的标签,发现更多相似文章
评论