Flutter 開發從 0 到 1(三)佈局與 ListView

上週日出去玩了,所以沒時間寫文章。我司加班到 11 點,次日能夠晚上班一個小時,加班到 12 點,能夠晚上班兩個小時,以此類推,爲何說這個,對的,加班次日我沒有多睡覺,而是起來抓緊時間寫文章,好了,廢話很少說,進入今天的主題。markdown

佈局

說到 Android 佈局,不是很難,會在對應的 xml 里布局,Flutter 裏沒有 xml,都在代碼裏寫,給人感受就很難,看下咱們要實現的佈局:網絡

打開 PhotoShop,看下背景色 #ededed,日期字體顏色 #a6a6a6,標題字體顏色 #1b1b1b,摘要字體顏色 #808080。app

公衆號這是列表,我先將 item 搞定。看這佈局都是線性佈局,這要在以前,分分鐘搞定,但 Flutter……好吧,Flutter 佈局可沒那麼簡單,我花了好幾個小時才作好,期間遇到了很多困難。框架

Flutter 也有橫向 Row 佈局和豎向 Column 佈局,我本想分 1 和 2 兩個部分,最外層豎向 Column 包含 1 和 2,2 自己是 Column,包含一個 image 和兩個 text,直接使用 Column 能夠完成,當我須要設置 2 裏面白色的背景色,發現 Column 根本沒有背景色屬性,因而把 2 最外層改形成 Container。ide

使用 Container 沒有問題,佈局也很快實現了,接下來是實現四角的圓角效果。oop

Container 有 decoration,能夠實現圓角,我遇到了兩個問題:佈局

一、當 shape: BoxShape.circle 時不能設置 borderRadius ,會異常 異常信息:'shape != BoxShape.circle ||borderRadius == null': is not true.學習

二、使用 BoxDecoration
Container 不能使用 color,會報錯: Cannot provide both a color and a decoration To provide both, use "decoration: BoxDecoration(color: color)".字體

覺得這樣就實現了圓角,不,不會那麼順利的,發現圖片根本沒有圓角效果,這和以前 Java 實現方式不同,最外層都實現了圓角,對裏面的佈局(圖片)竟然沒有生效,最後只好把佈局實現以下:ui

分紅 一、二、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 佈局的東西還有不少,其屬性讓人眼花撩亂,能夠去官網一個個去仔細學習和實踐。

ListView

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 加載更多。

相關文章
相關標籤/搜索