Flutter 實戰:擼半個知乎日報~ThemeListPage

fir_release_Android包下載地址

GIF

themelist.gif

UI如圖

themelisgpage.png

需求分析:

  • 整體滑動
  • 背景,標題,頂部導航欄聯動,漸隱漸出動畫
  • 裝載數據

UI拆解并實現:

  • CustomScrollView: 負責整體滑動

var content = new CustomScrollView(
      //沒有鋪滿也可以滑動
      physics: AlwaysScrollableScrollPhysics(),
      ........
      ........  
    )
  • SliverAppBar:背景,標題,頂部導航欄聯動,漸隱漸出動畫

new SliverAppBar(
          expandedHeight: _appBarHeight,
          pinned: _appBarBehavior == AppBarBehavior.pinned,
          floating: _appBarBehavior == AppBarBehavior.floating ||
              _appBarBehavior == AppBarBehavior.snapping,
          snap: _appBarBehavior == AppBarBehavior.snapping,
          flexibleSpace: new FlexibleSpaceBar(
            //標題
            title: Text('$_title'),
            //背景圖
            background: new FadeInImage.memoryNetwork(
                placeholder: kTransparentImage,
                image: _barBg,
                fit: BoxFit.fitHeight), 
          ),
        )

  • SliverList:

拆解1:主編一欄
Widget _buildEditor() {
   
   //橫向控件的集合
   List<Widget> editors = [];
   
   //主編
   Widget lableWidget = new Padding(
     padding: const EdgeInsets.only(right: 12.0),
     child: new Text(
       '主編',
       style: new TextStyle(fontSize: 14.0),
     ),
   );

   editors.add(lableWidget);
   
   //循環加入主編的頭像
   for (ThemeListEditorsModel model in _editorDatas) {
     Widget headView = new InkWell(
       onTap: () {
         RouteUtil.route2Web(context, model.name, model.url);
       },
       child: new Padding(
           padding: const EdgeInsets.only(
               left: 6.0, right: 6.0, top: 12.0, bottom: 12.0),
           child: new CircleAvatar(
             radius: 12.0,
             backgroundImage: new NetworkImage(model.avatar),
           )),
     );
     editors.add(headView);
   }

   //組裝
   return new Column(
     children: <Widget>[
       new Padding(
         padding: const EdgeInsets.only(left: 12.0, right: 12.0),
         child: new Row(
           children: editors,
         ),
       ),
       CommonDivider.buildDivider(),
     ],
   );
 }
拆解2:基礎item
Widget _buildNormalItem(ThemeListStoriesModel item) {
   final List images = item.images;
   final String title = item.title;
   final int id = item.id;
   bool hasImage = (null != images && images.isNotEmpty);

   if (hasImage) {
     return new InkWell(
         onTap: () {
           RouteUtil.route2Detail(context, '$id');
         },
         child: new Padding(
             padding: const EdgeInsets.only(left: 12.0, right: 12.0),
             child: new SizedBox(
               height: Constant.normalItemHeight,
               child: new Column(
                 children: <Widget>[
                   new Row(
                     children: <Widget>[
                       new Expanded(
                         child: new Text(
                           title,
                           style: new TextStyle(
                               fontSize: 16.0, fontWeight: FontWeight.w300),
                         ),
                       ),
                       new Padding(
                         padding: const EdgeInsets.all(8.0),
                         child: new SizedBox(
                           height: 80.0,
                           width: 80.0,
                           child: new Image.network(images[0]),
                         ),
                       )
                     ],
                   ),
                   new Expanded(
                     child: new Align(
                       alignment: Alignment.bottomCenter,
                       child: CommonDivider.buildDivider(),
                     ),
                   ),
                 ],
               ),
             )));
   } else {
     return new InkWell(
         onTap: () {
           RouteUtil.route2Detail(context, '$id');
         },
         child: new Padding(
             padding: const EdgeInsets.only(left: 12.0, right: 12.0),
             child: new SizedBox(
               height: Constant.normalItemHeight,
               child: new Column(
                 children: <Widget>[
                   new Row(
                     children: <Widget>[
                       new Expanded(
                         child: new SizedBox(
                           height: Constant.normalItemHeight,
                           child: new Align(
                             alignment: Alignment.centerLeft,
                             child: new Text(
                               title,
                               style: new TextStyle(
                                   fontSize: 16.0,
                                   fontWeight: FontWeight.w300),
                             ),
                           ),
                         ),
                       ),
                     ],
                   ),
                   new Expanded(
                     child: new Align(
                       alignment: Alignment.bottomCenter,
                       child: CommonDivider.buildDivider(),
                     ),
                   ),
                 ],
               ),
             )));
   }
 }
拆解3:根據類型顯示item
 Widget _buildNewItem(ThemeListStoriesModel item) {
   Widget widget;

   switch (item.itemType) {
     case ThemeListStoriesModel.itemTypeEditor:
       widget = _buildEditor();
       break;
     case ThemeListStoriesModel.itemTypeNormal:
       widget = _buildNormalItem(item);
       break;
   }
   return widget;
 }
拆解4:組裝
new SliverList(
         delegate: new SliverChildListDelegate(
             new List<Widget>.generate(_normalDatas.length, (int i) {
           return _buildNewItem(_normalDatas[i]);
         })),
       ),

拆解5:刷新
 var _refreshIndicator = new NotificationListener(
      onNotification: _onNotification,
      child: new RefreshIndicator(
        key: _refreshIndicatorKey,
        onRefresh: _refreshData,
        child: content,
      ),
    );
拆解6:加載更多
  void _scrollListener() {
    //滑到最底部刷新
    if (_scrollController.position.pixels ==
        _scrollController.position.maxScrollExtent) {
      _loadData();
    }
  }
  

已有項目集成到Flutter代碼已經上傳到我的GITHUB

知乎日報Flutter版代碼已經上傳到我的GITHUB

基礎學習過程中的代碼都放在GITHUB

每天學一點,學到Flutter發布正式版!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,132評論 25 708
  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網絡請求組件 FMDB本地數據庫組件 SD...
    陽明AGI閱讀 16,008評論 3 119
  • ——做一件事影響一群人 1.01的365次方等于37.8。 你每天能夠進步一點點,水滴石穿,最后你就能夠成就像滾雪...
    聽見花開3閱讀 300評論 0 0
  • 多久沒這樣一個人走走了,一手插著衣袋,一手握著手機,聽著緩緩的曲子,踏著悠悠的步子,目視前方,嘴角上揚。 朦朧的夜...
    默久安閱讀 370評論 0 2
  • 我的合租人是一位男士。不巧,他是個高級廚師,而我,拿手菜是煮泡面。蹭飯就這么理所當然的發生了。 我的合租人,不定時...
    太陽星宿閱讀 166評論 0 0