源码:
import 'dart:math';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:***/common/widgets/nomultiges.dart';
import 'package:***/common/widgets/refreshwidget.dart';
import 'package:***/generated/l10n.dart';
import 'package:***/module/session/provider/backlog_provider.dart';
import '/basic/basic_header.dart';
class BacklogPage extends StatefulWidget {
@override
_BacklogPageState createState() => _BacklogPageState();
}
class _BacklogPageState extends State {
@override
Widget build(BuildContext context) {
return Store.init(
providers: [ChangeNotifierProvider(create: (ctx) => BacklogProvider())],
child: Scaffold(
body: _Content(),
appBar: appBar(context,title: S.current.backlog,actions: [_SortButton()]),
),
);
}
}
class _SortButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return NoMultiGes(
child: Container(
width: 56,
height: 56,
color: Colors.transparent,
alignment: Alignment.center,
child: Transform.rotate(
angle: pi/2,
child: Image.asset(
R.assetsImgCommonMore,
width: 56.fitWidth(),
height: 56.fitWidth(),
),
),
),
onTap: _clickedAction(),
);
}
_clickedAction() {
}
}
class _Content extends StatefulWidget{
@override
State createState() => _ContentState();
}
class _ContentState extends State<_Content> {
RefreshController _refreshController = RefreshController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
initialIndex: 1,
child: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
_searchBar(),
_tabBar(),
];
},
body: TabBarView(
children: [
Container(width: double.infinity,height: 200,color: Colors.cyan,),
Container(width: double.infinity,height: 400,color: Colors.purple,),
RefreshWidget(
controller: _refreshController,
onRefresh: _refreshAction,
child: ListView.builder(
itemCount: 30,
itemBuilder: (ctx,index) {
return Container(
height: 50,
color: index % 2 == 0 ? Colors.white : Colors.black12,
width: double.infinity,
alignment: Alignment.center,
child: Text("我是第${index}个item"),
);
},
),
),
],
)
),
);
}
Widget _searchBar() {
return SliverToBoxAdapter(
child: Container(height: 44,width: double.infinity,color: Colors.amberAccent,),
);
}
Widget _tabBar() {
return SliverPersistentHeader(
pinned: true, //是否固定在顶部
floating: true,
delegate: _SliverAppBarDelegate(
minHeight: 50, //收起的高度
maxHeight: 50, //展开的最大高度
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
fit: FlexFit.tight,
child: TabBar(
tabs: [
Tab(
text: "Tab1",
),
Tab(
text: "Tab2",
),
Tab(
text: "Tab3",
),
],
isScrollable: false,
indicatorSize: TabBarIndicatorSize.label,
labelColor: Colors.black87,
unselectedLabelColor: Colors.grey,
),
),
Container(
width: 80,
color: Colors.blueAccent,
)
],
),
),
);
}
_refreshAction() {
_refreshController.refreshCompleted();
}
}
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 Container(color: Colors.white,child: child,);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}