NestedScrollView使用的Flutter Candies全家桶的 extended_nested_scroll_view
先上圖
兩種效果實現方式一致,只需要修改maxHeight大於minHeight
import 'package:bilibili_player_header/widget/CustomSliverPersistentHeader.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/material.dart' hide NestedScrollView;
class Demo1 extends StatefulWidget {
@override
_Demo1State createState() => _Demo1State();
}
class _Demo1State extends State<Demo1> with TickerProviderStateMixin {
ScrollController _sc = ScrollController();
bool _isShowTitle = false;
double _opacity = 0;
double height = 0;
double pinHeight = 300;
double playerHeight = 300;
double maxHeight = 300;
/// 滾動顯示_isShowTitle
double isShowHeight = 100;
bool isPlay = true;
@override
void initState() {
_sc.addListener(offsetListener);
super.initState();
}
offsetListener() {
setState(() {
height = _sc.offset;
});
if ((maxHeight - _sc.offset) < isShowHeight && !_isShowTitle) {
_isShowTitle = true;
_opacity = 1;
setState(() {});
} else if ((maxHeight - _sc.offset) > isShowHeight && _isShowTitle) {
_opacity = 0;
_isShowTitle = false;
setState(() {});
}
}
@override
void dispose() {
_sc.removeListener(offsetListener);
_sc.dispose();
super.dispose();
}
toPlay() {
isPlay = !isPlay;
pinHeight = isPlay ? playerHeight : kToolbarHeight;
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
toPlay();
},
child: Text('${!isPlay ? '播放' : '暫停'}'),
),
body: Stack(
children: <Widget>[
NestedScrollView(
controller: _sc,
headerSliverBuilder: (ctx, b) {
return [
SliverPersistentHeader(
delegate: CustomSliverPersistentHeader(
child: GestureDetector(
onDoubleTap: () {
toPlay();
},
child: Container(
height: maxHeight - height >= playerHeight ? maxHeight - height :playerHeight ,
// color: Colors.red,
child: Image.asset('assets/images/1.jpg'),
),
),
maxHeight: maxHeight,
minHeigth: playerHeight),
),
];
},
pinnedHeaderSliverHeightBuilder: () {
return pinHeight;
},
innerScrollPositionKeyBuilder: () {
return Key('tab1');
},
body: ListView(
children: List.generate(50, (index) {
return ListTile(
title: Text('$index'),
);
}),
),
),
IgnorePointer(
child: AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: _opacity,
child: Container(
color: Theme.of(context).primaryColor,
height: maxHeight - height,
),
),
),
if (_isShowTitle)
Container(
height: kToolbarHeight,
child: Center(
child: GestureDetector(
onTap: () {
toPlay();
},
child: Text('立即播放'),
),
),
)
],
),
);
}
}
複製程式碼