上週日出去玩了,所以沒時間寫文章。我司加班到 11 點,次日能夠晚上班一個小時,加班到 12 點,能夠晚上班兩個小時,以此類推,爲何說這個,對的,加班次日我沒有多睡覺,而是起來抓緊時間寫文章,好了,廢話很少說,進入今天的主題。網絡
說到 Android 佈局,不是很難,會在對應的 xml 里布局,Flutter 裏沒有 xml,都在代碼裏寫,給人感受就很難,看下咱們要實現的佈局:app
打開 PhotoShop,看下背景色 #ededed,日期字體顏色 #a6a6a6,標題字體顏色 #1b1b1b,摘要字體顏色 #808080。框架
公衆號這是列表,我先將 item 搞定。看這佈局都是線性佈局,這要在以前,分分鐘搞定,但 Flutter……好吧,Flutter 佈局可沒那麼簡單,我花了好幾個小時才作好,期間遇到了很多困難。ide
Flutter 也有橫向 Row 佈局和豎向 Column 佈局,我本想分 1 和 2 兩個部分,最外層豎向 Column 包含 1 和 2,2 自己是 Column,包含一個 image 和兩個 text,直接使用 Column 能夠完成,當我須要設置 2 裏面白色的背景色,發現 Column 根本沒有背景色屬性,因而把 2 最外層改形成 Container。佈局
使用 Container 沒有問題,佈局也很快實現了,接下來是實現四角的圓角效果。學習
Container 有 decoration,能夠實現圓角,我遇到了兩個問題:字體
一、當 shape: BoxShape.circle 時不能設置 borderRadius ,會異常
異常信息:'shape != BoxShape.circle ||borderRadius == null': is not true.ui
二、使用 BoxDecoration
Container 不能使用 color,會報錯:
Cannot provide both a color and a decoration
To provide both, use "decoration: BoxDecoration(color: color)"..net
覺得這樣就實現了圓角,不,不會那麼順利的,發現圖片根本沒有圓角效果,這和以前 Java 實現方式不同,最外層都實現了圓角,對裏面的佈局(圖片)竟然沒有生效,最後只好把佈局實現以下:code
分紅 一、二、3 部分,3 仍是 Container,2 和 3 圓角效果只對上下部分分別實現,完整代碼以下:
blogItem() { var date = new Padding( padding: const EdgeInsets.only( top: 20.0, left: 10.0, right: 10.0, ), child: new Text( '2020年6月28日 22:49', textAlign: TextAlign.center, style: TextStyle(color: ColorCommon.dateColor, fontSize: 18), )); var cover = new Padding( padding: const EdgeInsets.only( top: 10.0, left: 10.0, right: 10.0, ), child: new ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)), child: new Image.network( 'http://pic1.win4000.com/wallpaper/2020-04-21/5e9e676001e20.jpg', ))); var title = new Text( 'APP 開發從 0 到 1(一)需求與準備', style: TextStyle(color: ColorCommon.titleColor, fontSize: 22), ); var summary = new Padding( padding: const EdgeInsets.only( top: 5.0, ), child: new Text('一我的作一個項目,你也能夠。', textAlign: TextAlign.left, style: TextStyle(color: ColorCommon.summaryColor, fontSize: 18))); var titleSummary = new Container( padding: const EdgeInsets.all(10.0), alignment: Alignment.topLeft, decoration: new BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(10.0), bottomRight: Radius.circular(10.0)), shape: BoxShape.rectangle, ), margin: const EdgeInsets.only(left: 10, right: 10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: <Widget>[title, summary], ), ); var blogItem = new Column( children: <Widget>[date, cover, titleSummary, date, cover, titleSummary], ); return blogItem; }
實際效果以下:
好了,關於 Flutter 佈局就講到這裏,我只是針對這個項目所須要的去實現,Flutter 佈局的東西還有不少,其屬性讓人眼花撩亂,能夠去官網一個個去仔細學習和實踐。
blogItem 寫好了,完成了大頭,接下來就要填充真實的數據,在《APP 開發從 0 到 1(二)框架與網絡》,有說到網絡請求,其中有提到 setstate(){} 方法,調用這個方法會回調 build 方法,這樣咱們能夠在 build 方法加個判斷,先加載 Progress,待網絡數據請求完,再顯示 ListView,代碼以下:
@override Widget build(BuildContext context) { var content; if (blogList.isEmpty) { content = new Center( // 可選參數 child: child: new CircularProgressIndicator(), ); } else { content = new ListView(children: blogItem()); } return Scaffold( backgroundColor: ColorCommon.backgroundColor, appBar: AppBar( title: Text('AndBlog'), ), body: content, floatingActionButton: FloatingActionButton( tooltip: 'Increment', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } blogItem() { List<Widget> widgets = []; for (int i = 0; i < blogList.length; i++) { Blog blog = blogList[i]; var date = new Padding( padding: const EdgeInsets.only( top: 20.0, left: 10.0, right: 10.0, ), child: new Text( // 填充真實數據 blog.date, textAlign: TextAlign.center, style: TextStyle(color: ColorCommon.dateColor, fontSize: 18), )); //…… var blogItem = new Column( children: <Widget>[ date, cover, titleSummary, ], ); widgets.add(blogItem); } return widgets; }
這樣 ListView 也完成了,接下來須要完成的是 ListView 加載更多。