滑动折叠效果为什么这么火。除了符合用户操作习惯 突出内容焦点 配上流畅的动画 基本在被绝大数产品和app所使用。

normal video.mp4 (1.67MB)
效果:
上滑隐藏头部折叠区域 | 下滑展开折叠区域| tab可以滑动以及切换底部内容区域 | 顶部标题栏固定操作(可配置跟随滑动隐藏显示)

构成:
NestedScrollView + SliverAppBar + tabbar

image.png
image.png
image.png

布局构成:

1 使用NestedScrollView的headerSliverBuilder定义SliverAppBar构建滑动的折叠区域

flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
centerTitle: true,
//background: PeotryWidget(“将进酒”,”【唐】李白”,”君不见,黄河之水天上来
\r 奔流到海不复回 \r\n 君不见,高堂明镜悲白发, \r 朝如青丝暮成雪”‘), _background: Image.asset(Constant._dir_image
+widget.option.params[“gifimage”],fit: BoxFit.contain),
),

2使用SliverAppBar 的 leading 构建导航栏

leading: new IconButton(
icon: Icon(Icons.arrow_back,color: ColorsConfig.primaryColor,),
onPressed: () { Navigator.pop(context);},
),

actions: [//构建右侧菜单
Observer(builder: () =>new IconButton( // action button icon: Icon(_peotryModel.isLike()?Icons._favorite:Icons.favorite_border,color: ColorsConfig.PRIMARY_YELLOW),
onPressed: () {
_peotryModel.setLike(!_peotryModel.isLike());
},
))
],

3 bottom构建底部tabbar

bottom: BaseViewBar(preferredSize: Size.fromHeight(160.0),childView:Column(children:[
PeotryViewWidget(content:widget.option.params[“content”]),new TabBar(
indicatorColor:ColorsConfig.primaryColor,
controller: _tabController,
labelColor: ColorsConfig.PRIMARY_GRAY_333,
labelStyle: TextStyle(fontSize: 18,decorationStyle: TextDecorationStyle.dashed),
isScrollable: true,
tabs: choices.asMap().keys.map( (key) {
return new Tab(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(child:Center(child:
Text(choices.elementAt(key).title))),
],
)
//icon: new Icon(choice.icon), );
}).toList())]),
) ,
插曲:因为SliverAppBar的折叠区域background定义只能是image 但是需求上需要在image下面定义一些文字。如果把自定义的非imageWidget放在backgroud上就会失败。(~~)所以尝试在bottom 的tabbar上面添加了文字。但需要widget 是preferredWidget!!!(效果业不是特别好~后续可能自己自定义控制滑动来实现)

4 NestedScrollView 的body定义底部显示区域

body: buildBottom()
Widget _buildBottom(){
return _fixTabBarView=FixTabBarView(pageController: _pageController,tabController: _tabController, children: choices.map((Choice choice) {
return new Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 16),
child: Padding(padding:EdgeInsets.all(14) ,child:Text(
choice.content,
style: Theme._of
(context).textTheme.body2,
),
));
}).toList());
}

总体感觉flutter的布局体系虽然简单分为容器类 (Container、ConstrainedBox、BoxDecoration)、 展示类(Image、Text、Icon、Swtich、Checkbox) 布局类(Row 、Column、Flex、warp,层叠布局stack和postioned ,Align、Center),功能类(InheritedWidget、FutureBuilder、StreamBuilder)

知识点:

1 text宽度超出屏幕:a 外部嵌套Container 设置width 然后text设置overflow: TextOverflow.ellipsis
b 外部嵌套warp
2 SleverAppbar 折叠区域只能是ImageWidget
_//是否随着滑动隐藏标题_floating: false,
_//tab 是否固定在顶部_pinned:
true,
_//与floating结合使用_snap:
false**,