# 本文收穫與價值
看完本系列文章後你將能夠做出如下100%還原攜程 V8.22.0
首頁 GridNav
的介面:
# 準備工作
開始前請
-
按照Flutter一步步實現x程GridNav網格佈局_準備工作中的步驟完成準備工作;
-
按照Flutter一步步實現x程GridNav網格佈局_整體佈局中新增相關程式碼;
注: 以下全部程式碼改變都在grid_widget.dart
檔案中機進行;
# 實現hotel行的佈局
-
將
// todo: add hotel row
替換為child: Row( children: <Widget>[ // todo: add hotel row items ], ), 複製程式碼
-
在
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: 23
和flex 46
等均是如此; -
FractionallySizedBox(widthFactor: 1,heightFactor: 1)
是用來撐滿父節點整個佈局空間用的,widthFactor: 1
代表比例表示佔滿寬,heightFactor: 1
表示佔滿高度;
-
-
將如下程式碼新增到
// todo: add hotel row items
的下方_firstBGimageStack(), 複製程式碼
儲存更改
cmd
+s
,介面熱更新如下 -
在
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, ), ); } 複製程式碼
-
在
_hotelRow()
方法的// todo: add hotel row items
的下方新增_secondBGImageStack(),
,cmd
+s
儲存後熱更新介面如下: -
新增
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
儲存並熱跟新後介面如下: -
實現
方便又便宜
的佈局,在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
儲存並熱跟新後介面效果如下:
至此 hotel
行的佈局全部完成?
# 完成 flightRow 和 travelRow
前面我們已經封裝好了 _firstBGimageStack
和 _secondBGImageStack
函式,這裡我們給他們新增必要的引數就能實現背景圖和標題的更換,現在開始動手吧:
-
將備註
// 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.
備註; -
同
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.
備註; -
將
_hotelRow
函式內部中呼叫上述_firstBGimageStack()
,_secondBGImageStack()
傳入相應引數,修改如下_firstBGimageStack( imageUrl: _hotelBGImageUrl, title: '酒店', ), _secondBGImageStack( imageUrl: _minsuBGImageUrl, title: '民宿·客棧', ), 複製程式碼
並刪除
// todo: add hotel row items
的備註,然後cmd
+s
儲存並熱更新後介面應該保持不變; -
新增無背景圖的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, ), ); } 複製程式碼
-
開始替換
_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
儲存並熱更新後介面如下: -
同樣替換
_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地址