需求介绍
在主页中,需要实现既能上下滚动,又要有吸顶效果,并且吸顶效果下还需要实现TabBar与PageView的结合。
就像掘金的主页交互一样。
看效果
代码
dart
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class HomeView extends GetView<HomeController> {
const HomeView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
child: DefaultTabController(
length: 2,
child: Column(
children: [
Expanded(
child: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverToBoxAdapter(
child: Container(
color: Colors.blue,
height: 200,
),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(
minHeight: 50,
maxHeight: 50,
child: Container(
color: Colors.green,
),
),
pinned: true,
),
];
},
body: PageView(
children: <Widget>[
CustomScrollView(
slivers: [
SliverList(
delegate:
SliverChildBuilderDelegate((context, index) {
return ListTile(
title: Text('index $index'),
);
}, childCount: 100),
)
],
),
CustomScrollView(
slivers: [
SliverList(
delegate:
SliverChildBuilderDelegate((context, index) {
return ListTile(
title: Text('index $index'),
);
}, childCount: 100),
)
],
),
],
),
),
),
Container(
height: 30,
)
],
),
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
required this.minHeight,
required this.maxHeight,
required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
@override
double get minExtent => minHeight;
@override
double get maxExtent => max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return SizedBox.expand(child: child);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}