Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結

CobableKun發表於2020-04-10

# 本文收穫與價值

看完本系列文章後你將能夠做出如下100%還原攜程 V8.22.0 首頁 GridNav 的介面:

Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結

# 準備工作

開始前請

  1. 按照Flutter一步步實現x程GridNav網格佈局_準備工作中的步驟完成準備工作;

  2. 按照Flutter一步步實現x程GridNav網格佈局_整體佈局中新增相關程式碼;

注: 以下全部程式碼改變都在grid_widget.dart檔案中機進行;

# 實現hotel行的佈局

  1. // todo: add hotel row 替換為

    child: Row(
      children: <Widget>[
        // todo: add hotel row items
      ],
    ),
    複製程式碼
  2. Widget _travelRow(){... 函式下面新增如下程式碼實現

    // todo: add imageUrl, imgWidth,title. 
    Widget _firstBGimageStack() {
      return Expanded(
        child: FractionallySizedBox(
          widthFactor: 1,
          heightFactor: 1,
          child: Stack(
            alignment: Alignment.bottomRight,
            children: <Widget>[
              _bgImagePositioned(
                _hotelBGImageUrl,
                width: imgWidth,
              ),
              _firstTitlePositioned('酒店'),
            ],
          ),
        ),
        flex: 31,
      );
    }
    
    Widget _firstTitlePositioned(String title) {
      return Positioned(
        left: 15,
        top: 25,
        child: Text(
          title,
          style: _titleStyle,
        ),
      );
    }
    
    Widget _bgImagePositioned(String imageUrl, {double width = 73}) {
      return Positioned(
        child: Image.network(
          imageUrl,
          width: width,
          fit: BoxFit.fill,
        ),
      );
    }
    
    複製程式碼

    注意:

    • _firstBGimageStack 中的 flex: 31 是根據網頁端的flex佈局的比例來的,下文中 flex: 23flex 46 等均是如此;

    • FractionallySizedBox(widthFactor: 1,heightFactor: 1)是用來撐滿父節點整個佈局空間用的,widthFactor: 1 代表比例表示佔滿寬, heightFactor: 1表示佔滿高度;

  3. 將如下程式碼新增到 // todo: add hotel row items 的下方

    _firstBGimageStack(),
    複製程式碼

    儲存更改cmd+s,介面熱更新如下

    Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結
  4. Widget _bgImagePositioned(){... 函式下方新增第二列帶有背景圖的 Stack 佈局程式碼(包括新增左邊框):

    // todo: add imageUrl, imgWidth,title. 
    Widget _secondBGImageStack() {
      return Expanded(
        child: FractionallySizedBox(
          widthFactor: 1,
          heightFactor: 1,
          child: Container(
            decoration: BoxDecoration(
              border: Border(
                left: _borderSide,
              ),
            ),
            child: Stack(
              alignment: Alignment.bottomLeft,
              children: <Widget>[
                _bgImagePositioned(
                  _minsuBGImageUrl,
                  width: 37,
                ),
                _commonTitle('民宿·客棧'),
              ],
            ),
          ),
        ),
        flex: 23,
      );
    }
    
    Widget _commonTitle(String title) {
      return Center(
        child: Text(
          title,
          style: _titleStyle,
        ),
      );
    }
    複製程式碼
  5. _hotelRow()方法的 // todo: add hotel row items 的下方新增 _secondBGImageStack(), , cmd+s 儲存後熱更新介面如下:

    Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結
  6. 新增 platform 檢視的佈局程式碼,在 Widget _commonTitle(String title){...函式下方新增如下程式碼:

    Widget _platformBGImageStack() {
      return Expanded(
        child: FractionallySizedBox(
          widthFactor: 1,
          heightFactor: 1,
          child: Container(
            decoration: BoxDecoration(
              border: Border(
                left: _borderSide,
              ),
              gradient: LinearGradient(colors: _platformColors),
            ),
            child: Stack(
              alignment: Alignment.bottomRight,
              children: <Widget>[
                _bgImagePositioned(_platformBGImage, width: 86),
                _platformTitle('機票/火車票+酒店 '),
                // todo: add platform tag
              ],
            ),
          ),
        ),
        flex: 46,
      );
    }
    
    Widget _platformTitle(String title) {
      return Center(
        child: Text(
          title,
          style: _platformStyle,
        ),
      );
    }
    複製程式碼

    _hotelRow()方法的 // todo: add hotel row items 下方新增

    _platformBGImageStack(),
    複製程式碼

    cmd+s儲存並熱跟新後介面如下:

    Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結
  7. 實現方便又便宜的佈局,在 Widget _platformTitle(String title) {...函式的下方新增如下程式碼

    Widget _platformTagTilte(String title) {
      return Center(
        child: Padding(
          padding: EdgeInsets.only(
            bottom: 32,
            left: 38,
          ),
          child: Container(
            decoration: BoxDecoration(
              color: Color(0xfff54c45),
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(7),
                topRight: Radius.circular(7),
                bottomRight: Radius.circular(7),
              ),
            ),
            padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
            child: Text(
              title,
              style: TextStyle(
                color: Color(0xffffffff),
                fontSize: 12,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
        ),
      );
    }
    複製程式碼

    然後將 // todo: add platform tag 替換為 _platformTagTilte('方便又便宜'), 隨後 cmd+s儲存並熱跟新後介面效果如下:

    Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結

至此 hotel 行的佈局全部完成?

# 完成 flightRow 和 travelRow

前面我們已經封裝好了 _firstBGimageStack_secondBGImageStack 函式,這裡我們給他們新增必要的引數就能實現背景圖和標題的更換,現在開始動手吧:

  1. 將備註 // todo: add imageUrl, imgWidth,title.Widget _firstBGimageStack(){正行程式碼,替換為如下:

    Widget _firstBGimageStack({
      @required String imageUrl,
      double imgWidth = 73,
      String title,
    }) {
    複製程式碼

    並將其內部的 _hotelBGImageUrl 替換為傳入的 imageUrl, 37 替換為傳入的 imgWidth, 酒店替換為傳入的 title, 刪除 // todo: add imageUrl, imgWidth,title. 備註;

  2. 1 中的操作將備註 // todo: add imageUrl, imgWidth,title.Widget _secondBGImageStack() {正行程式碼,替換為如下:

    Widget _secondBGImageStack({
      @required String imageUrl,
      double imgWidth = 37,
      String title,
    }) {
    複製程式碼

    並將其內部的 _minsuBGImageUrl 替換為傳入的 imageUrl, 73 替換為傳入的 imgWidth, 民宿·客棧替換為傳入的 title,刪除 // todo: add imageUrl, imgWidth,title. 備註;

  3. _hotelRow 函式內部中呼叫上述_firstBGimageStack(),_secondBGImageStack()傳入相應引數,修改如下

    _firstBGimageStack(
      imageUrl: _hotelBGImageUrl,
      title: '酒店',
    ),
    _secondBGImageStack(
      imageUrl: _minsuBGImageUrl,
      title: '民宿·客棧',
    ),
    複製程式碼

    並刪除 // todo: add hotel row items 的備註,然後 cmd+s儲存並熱更新後介面應該保持不變;

  4. 新增無背景圖的items佈局

    Widget _noBGImageStack({@required String title}) {
      return Expanded(
        child: FractionallySizedBox(
          widthFactor: 1,
          heightFactor: 1,
          child: Container(
            decoration: BoxDecoration(
              border: Border(
                left: _borderSide,
              ),
            ),
            child: _commonTitle(title),
          ),
        ),
        flex: 23,
      );
    }
    
    Widget _commonTitle(String title) {
      return Center(
        child: Text(
          title,
          style: _titleStyle,
        ),
      );
    }
    複製程式碼
  5. 開始替換 _flightRow() 中的 // todo: add flight row 為如下程式碼;

    child: Row(
      children: <Widget>[
        _firstBGimageStack(
          imageUrl: _flightBGImageUrl,
          imgWidth: 79,
          title: '飛機',
        ),
        _secondBGImageStack(
          imageUrl: _trainBGImage,
          imgWidth: 37,
          title: '火車票',
        ),
        _noBGImageStack(title: '汽車·船票'),
        _noBGImageStack(title: '專車·租車'),
      ],
    ),
    複製程式碼

    然後 cmd+s 儲存並熱更新後介面如下:

    Flutter一步步實現x程GridNav網格佈局_hotel佈局與完結
  6. 同樣替換 _travelRow 中的 // todo: add travel row 為如下程式碼:

    child: Row(
      children: <Widget>[
        _firstBGimageStack(
          imageUrl: _tripBGImage,
          imgWidth: 93,
          title: '旅遊',
        ),
        _secondBGImageStack(
          imageUrl: _dingzhiBGImage,
          imgWidth: 61,
          title: '高鐵遊',
        ),
        _noBGImageStack(title: '郵輪遊'),
        _noBGImageStack(title: '定製遊'),
      ],
    ),
    複製程式碼

    然後 cmd+s 儲存

至此,本文章全部程式碼結束,感謝您的閱讀,同時希望您能跟著自己動手親自試驗一下;

原文地址:Flutter實現攜程GirdNav佈局

附上deom地址

相關文章