需要使用滑动渐变在前面一篇文章中已经有提到过,那就是必须使用 CustomScrollView ,
而滑动渐变又离不开appbar,而CustomScrollView 中又引入SliverAppBar 这个控件
const SliverAppBar({
Key key,
this.leading,
this.automaticallyImplyLeading = true,
this.title,
this.actions,
this.flexibleSpace,
this.bottom,
this.elevation,
this.shadowColor,
this.forceElevated = false,
this.backgroundColor,
this.brightness,
this.iconTheme,
this.actionsIconTheme,
this.textTheme,
this.primary = true,
this.centerTitle,
this.excludeHeaderSemantics = false,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.collapsedHeight,
this.expandedHeight,
this.floating = false,
this.pinned = false,
this.snap = false,
this.stretch = false,
this.stretchTriggerOffset = 100.0,
this.onStretchTrigger,
this.shape,
this.toolbarHeight = kToolbarHeight,
})
这个里面很多属性在AppBar中都有说过,这里说一下剩下几个主要的属性
/// 停止拖动是否 继续响应拖动事件
snap: false,
/// 下滑过程中是否优先展开头部折叠部分 ,
floating: false,
///pinned(固定的) 控制隐藏和展示的 false 就是可以随列表滑出屏幕外 true 不可以
pinned: true,
onStretchTrigger: () {
printString('onStretchTrigger');
return;
},
expandedHeight: 200,///展开后的高度
flexibleSpace: Widget ,///展开后的控件
image.png
再来说一下
这三个属性
floating: true, pinned: false, 时 的滑动表现
GIF 2020-8-27 15-59-06.giffloating: false, pinned: true, 时 的滑动表现
GIF 2020-8-27 16-02-52.giffloating 如果为true 在下滑过程中优先展开折叠的部分
pinned false 就是可以随列表滑出屏幕外 true 不可以
SliverToBoxAdapter
在CustomScrollView 中是能使用Sliver系的控件,如果在CustomScrollView 中想要嵌套其他非 Sliver 系就必须要使用SliverToBoxAdapter包装一下,
来一个综合的例子
这个例子中我添加了下拉刷新部分,发现这个刷新部分放在哪个位置,哪个位置就有刷新的功能
class _TsmCustomScrollViewState extends State<TsmCustomScrollViewPage> {
@override
Widget build(BuildContext context) {
return Material(
child: CustomScrollView(
physics: BouncingScrollPhysics(),
///越界回弹效果
slivers: [
CupertinoSliverRefreshControl(
refreshIndicatorExtent: 60,
/// 刷新过程中悬浮高度
refreshTriggerPullDistance: 100,
///触发刷新的距离
/// 自定义布局
builder: (context, buildRefreshindictor, pulledExtent,
refreshTriggerPullDistance, refreshIndicatorExtent) {
printString(
'pulledExtent : ${pulledExtent} ,refreshTriggerPullDistance : ${refreshTriggerPullDistance} refreshIndicatorExtent:${refreshIndicatorExtent}');
return Container(
color: Colors.redAccent,
height: 150,
alignment: Alignment.center,
child: AnimatedOpacity(
duration: Duration(milliseconds: 300),
//opacity: top == 80.0 ? 1.0 : 0.0,
opacity: 1.0,
child: Text(
RefreshIndicatorMode.done == buildRefreshindictor
? '已拉动:${pulledExtent.round()} 松开刷新'
: '已拉动:${pulledExtent.round()} 下拉刷新',
style: TextStyle(fontSize: 12.0),
)),
);
},
///触发刷新回调
onRefresh: () async {
await Future.delayed(Duration(seconds: 3));
printString('CupertinoSliverRefreshControl onRefresh');
},
),
SliverAppBar(
centerTitle: true,
titleSpacing: 0,
title: Text(
'CustomScrollView',
style: TextStyle(color: Colors.black87),
),
/// 停止拖动是否 继续响应拖动事件
snap: false,
/// 下滑过程中是否优先展开头部折叠部分 ,
floating: false,
///pinned(固定的) 控制隐藏和展示的 false 就是可以随列表滑出屏幕外 true 不可以
pinned: true,
backgroundColor: Colors.blueAccent,
expandedHeight: 200,///展开后的高度
flexibleSpace: LayoutBuilder(
builder: (context, cons) {
return FlexibleSpaceBar(
// collapseMode: CollapseMode.pin,
background: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/hor.jpg'), fit: BoxFit.fill),
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
'这个是头部',
style: TextStyle(color: Colors.pink),
),
Text(
'这个是头部',
style: TextStyle(color: Colors.pink),
),
Text(
'这个是头部',
style: TextStyle(color: Colors.pink),
),
Text(
'这个是头部',
style: TextStyle(color: Colors.pink),
),
Text(
'这个是头部',
style: TextStyle(color: Colors.pink),
),
],
),
));
},
),
),
//
SliverPersistentHeader(
floating: true,
pinned: false,
delegate: _SliverPersistenHeaderDelegate(
minHeight: 50, maxHeight: 150, child: Text('1111')),
),
SliverSafeArea(
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
height: 50,
margin: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.all(Radius.circular(9)),
),
child: Center(
child: Text(index.toString()),
),
),
childCount: 50)),
)
],
),
);
}
}
class _SliverPersistenHeaderDelegate extends SliverPersistentHeaderDelegate {
double maxHeight;
double minHeight;
Widget child;
_SliverPersistenHeaderDelegate({this.maxHeight, this.minHeight, this.child});
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return SizedBox.expand(
child: child,
);
}
@override
double get maxExtent => max<double>(minHeight, maxHeight);
@override
// TODO: implement minExtent
double get minExtent => min<double>(minHeight, maxHeight);
@override
bool shouldRebuild(_SliverPersistenHeaderDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
我学习flutter的整个过程都记录在里面了
https://www.jianshu.com/c/36554cb4c804
最后附上demo 地址
网友评论