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(); } }
作者:老实巴交的读书人
链接:https://www.jianshu.com/p/265fd0fa6762