【Flutter 踩坑】螢幕寬度測量錯誤導致image不展示
上篇提到《Flutter獲取螢幕寬高和密度的方法》https://www.jianshu.com/p/0edcebc05279
現在來說說遇到的問題。
圖片的寬度為match螢幕。
首先度娘告訴我,獲取螢幕的寬度的方法如下:
MediaQuery.of(context).size.width
由於flutter不能想Android原生那樣,直接設定match_parent。所以只能設定widget的width和height。
下面先粘出自己摸索出來的程式碼:
//載入網路圖片 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'; constapi="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, ) ···