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阅读 175,298评论 25 709
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,040评论 3 119
  • ——做一件事影响一群人 1.01的365次方等于37.8。 你每天能够进步一点点,水滴石穿,最后你就能够成就像滚雪...
    听见花开3阅读 2,338评论 0 0
  • 多久没这样一个人走走了,一手插着衣袋,一手握着手机,听着缓缓的曲子,踏着悠悠的步子,目视前方,嘴角上扬。 朦胧的夜...
    默久安阅读 2,854评论 0 2
  • 我的合租人是一位男士。不巧,他是个高级厨师,而我,拿手菜是煮泡面。蹭饭就这么理所当然的发生了。 我的合租人,不定时...
    太阳星宿阅读 1,189评论 0 0