Untitled.gif
import 'package:flutter/material.dart';
import 'dart:math';
class CustomGradationNavigationBar extends StatefulWidget {
const CustomGradationNavigationBar({super.key});
@override
State<CustomGradationNavigationBar> createState() =>
_CustomGradationNavigationBarState();
}
class _CustomGradationNavigationBarState
extends State<CustomGradationNavigationBar> {
double _scrollDistance = 0.0;
final double _imageShowHeight = 300;
@override
Widget build(BuildContext context) {
final navHeight =
MediaQuery.of(context).padding.top + AppBar().preferredSize.height;
return RefreshIndicator(
onRefresh: () async {
return Future.delayed(Duration(seconds: 1), () {
print("刷新了======");
});
},
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Stack(
children: [
Positioned(
left: 0,
top: _scrollDistance < 0 ? min(_scrollDistance, 0) : 0,
bottom: 0,
right: 0,
child: Scaffold(
body: NotificationListener(
onNotification:
(ScrollUpdateNotification scrollNotification) {
if (scrollNotification.depth == 0) {
// print(scrollNotification.metrics.pixels);
setState(() {
_scrollDistance = scrollNotification.metrics.pixels;
});
}
return false;
},
child: CustomScrollView(
// physics: ClampingScrollPhysics(),
slivers: [
const SliverToBoxAdapter(),
//sliver很奇怪 会把最上面的那个悬浮,所以这里加一个空widgit使图片跟着下拉
SliverPersistentHeader(
delegate: MyDelegate(
//当下拉的时候_scrollDistance为负数 要图片放大 图片高度就是: maxHeight - _scrollDistance
//当上划的时候 图片高度不变 直接使用:maxHeight
imageShowHeight: _scrollDistance < 0
? (_imageShowHeight - _scrollDistance)
: _imageShowHeight,
imgUrl:
"https://img.zcool.cn/community/01c6615d3ae047a8012187f447cfef.jpg@1280w_1l_2o_100sh.jpg",
),
),
SliverList(
delegate: SliverChildBuilderDelegate((ctx, index) {
return Text("data: $index");
}, childCount: 100),
)
],
),
),
),
),
CustomNavBar(
scrollDistance: _scrollDistance,
imageShowHeight: _imageShowHeight),
],
),
),
);
}
}
class CustomNavBar extends StatelessWidget {
final double scrollDistance;
final double imageShowHeight;
const CustomNavBar({
super.key,
required this.scrollDistance,
required this.imageShowHeight,
});
@override
Widget build(BuildContext context) {
final navHeight =
MediaQuery.of(context).padding.top + AppBar().preferredSize.height;
//滚动距离是 0 滑到导航栏的高度, 这边做下渐变 如果距离小于0 那就直接设置透明度为0
final percent = scrollDistance > 0.0
? min(scrollDistance, imageShowHeight - navHeight) /
(imageShowHeight - navHeight)
: 0.0;
//print("percent: $percent, distance: $_scrollDistance, height: ${_imageShowHeight - navHeight}");
return SizedBox(
height: navHeight,
child: AppBar(
elevation: 0,
title: const Text("这里是标题"),
backgroundColor: Colors.red.withAlpha((percent * 255).toInt()),
),
);
}
}
class MyDelegate extends SliverPersistentHeaderDelegate {
final double imageShowHeight;
final String imgUrl;
MyDelegate({
required this.imageShowHeight,
required this.imgUrl,
});
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Image.network(
imgUrl,
fit: BoxFit.cover,
height: imageShowHeight,
);
}
@override
double get maxExtent => imageShowHeight;
@override
double get minExtent => imageShowHeight;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
}
网友评论