如何将居中的TabBarView移动到页面顶部?
How To Move The TabBarView in the Center to The Top of the Page?
我在页面中间有一个 TabBarView,它可以更改选项卡。选项卡 1 上的内容由 StaggeredGridView.countBuilder 创建,而第二个选项卡上的内容由 listview.builder 创建。
每个选项卡的内容都是可滚动的,但是只有TabBarView下面的内容是可滚动的。
有没有可能当我滚动页面时,TabBarView 也从屏幕中间移动到页面顶部并锁定在那里,以便整个屏幕可以充满每个选项卡的内容?
我看到有人建议将 SingleChildScrollView 用于 body 和物理学:NeverScrollableScrollPhysics() 用于 listview.builder。
这没有用。屏幕returns只是运行时的背景颜色。
您需要使用包含所有项目的自定义滚动视图。
- 您的个人资料详细信息小部件
- 标签栏
- 标签视图
让我们实现这个
缺点:无法固定应用栏
import 'package:flutter/material.dart';
class MyCustomScrollViewScreen extends StatefulWidget {
@override
_MyCustomScrollViewScreenState createState() =>
_MyCustomScrollViewScreenState();
}
class _MyCustomScrollViewScreenState extends State<MyCustomScrollViewScreen>
with TickerProviderStateMixin {
TabController tabController;
@override
Widget build(BuildContext context) {
tabController = TabController(length: 2, vsync: this);
return Scaffold(
body: SafeArea(
child: CustomScrollView(
slivers: [
SliverAppBar(
floating: true,
title: Text("AppBar"),
),
//profile widget
SliverToBoxAdapter(
key: UniqueKey(),
child: Container(
color: Colors.green,
height: 100,
child: Center(child: Text("Profile details")),
),
),
//tabbar
SliverPersistentHeader(
pinned: true,
floating: true,
delegate: MyCustomHeader(
expandedHeight: kToolbarHeight,
tabs: TabBar(
controller: tabController,
tabs: [
Icon(
Icons.ac_unit,
size: 30,
color: Colors.black,
),
Icon(
Icons.access_alarm,
size: 30,
color: Colors.black,
),
],
))),
//children
SliverFillRemaining(
child: TabBarView(
controller: tabController,
children: [
Center(child: Text("I'm 1")),
Center(child: Text("I'm 2"))
],
),
)
],
),
),
);
}
}
/// persistent header
class MyCustomHeader extends SliverPersistentHeaderDelegate {
MyCustomHeader({
@required this.expandedHeight,
this.tabs,
this.context,
});
final Widget tabs;
final double expandedHeight;
final BuildContext context;
@override
double get maxExtent => expandedHeight;
@override
double get minExtent => kToolbarHeight;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
child: tabs,
);
}
}
这是结果
我在页面中间有一个 TabBarView,它可以更改选项卡。选项卡 1 上的内容由 StaggeredGridView.countBuilder 创建,而第二个选项卡上的内容由 listview.builder 创建。
每个选项卡的内容都是可滚动的,但是只有TabBarView下面的内容是可滚动的。
有没有可能当我滚动页面时,TabBarView 也从屏幕中间移动到页面顶部并锁定在那里,以便整个屏幕可以充满每个选项卡的内容?
我看到有人建议将 SingleChildScrollView 用于 body 和物理学:NeverScrollableScrollPhysics() 用于 listview.builder。
这没有用。屏幕returns只是运行时的背景颜色。
您需要使用包含所有项目的自定义滚动视图。
- 您的个人资料详细信息小部件
- 标签栏
- 标签视图
让我们实现这个
缺点:无法固定应用栏
import 'package:flutter/material.dart';
class MyCustomScrollViewScreen extends StatefulWidget {
@override
_MyCustomScrollViewScreenState createState() =>
_MyCustomScrollViewScreenState();
}
class _MyCustomScrollViewScreenState extends State<MyCustomScrollViewScreen>
with TickerProviderStateMixin {
TabController tabController;
@override
Widget build(BuildContext context) {
tabController = TabController(length: 2, vsync: this);
return Scaffold(
body: SafeArea(
child: CustomScrollView(
slivers: [
SliverAppBar(
floating: true,
title: Text("AppBar"),
),
//profile widget
SliverToBoxAdapter(
key: UniqueKey(),
child: Container(
color: Colors.green,
height: 100,
child: Center(child: Text("Profile details")),
),
),
//tabbar
SliverPersistentHeader(
pinned: true,
floating: true,
delegate: MyCustomHeader(
expandedHeight: kToolbarHeight,
tabs: TabBar(
controller: tabController,
tabs: [
Icon(
Icons.ac_unit,
size: 30,
color: Colors.black,
),
Icon(
Icons.access_alarm,
size: 30,
color: Colors.black,
),
],
))),
//children
SliverFillRemaining(
child: TabBarView(
controller: tabController,
children: [
Center(child: Text("I'm 1")),
Center(child: Text("I'm 2"))
],
),
)
],
),
),
);
}
}
/// persistent header
class MyCustomHeader extends SliverPersistentHeaderDelegate {
MyCustomHeader({
@required this.expandedHeight,
this.tabs,
this.context,
});
final Widget tabs;
final double expandedHeight;
final BuildContext context;
@override
double get maxExtent => expandedHeight;
@override
double get minExtent => kToolbarHeight;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
child: tabs,
);
}
}
这是结果