Flutter文档展示了一个使用NestedScrollView
的SliverAppBar
+TabBar
+TabBarView with ListView
的演示,但这有点复杂,我想知道是否有更简单清晰的实现方法。我尝试了以下代码:
CustomScrollView
slivers:
SliverAPPBar
bottom: TabBar
TabBarView
children: MyWidget(list or plain widget)
出现错误:
Flutter: 在构建Scrollable(axisDirection: right, physics:
Flutter: A RenderViewport期望被子元素为RenderSliver类型,但接收到的是_RenderExcludableScrollSemantics类型.
Flutter: 渲染对象需要特定类型的子元素,因为它们在布局和绘制时需要与子元素协调。例如,一个RenderSliver不能成为RenderBox的子元素,因为RenderSliver不理解RenderBox的布局协议。
并且
Flutter: 另外一个异常被抛出:'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': 不为真。
这是我的代码:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyScrollTabListApp());
}
class MyScrollTabListApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(title: "aa", home: MyScrollTabListHomePage());
}
}
class MyScrollTabListHomePage extends StatefulWidget {
@override
MyScrollTabListHomePageState createState() {
return new MyScrollTabListHomePageState();
}
}
class MyScrollTabListHomePageState extends State<MyScrollTabListHomePage>
with SingleTickerProviderStateMixin {
final int _listItemCount = 300;
final int _tabCount = 8;
TabController _tabController;
@override
void initState() {
_tabController = TabController(length: _tabCount, vsync: this);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 240.0,
title: Text("Title"),
pinned: true,
bottom: TabBar(
controller: _tabController,
isScrollable: true,
tabs: List<Tab>.generate(_tabCount, (int i) {
return Tab(text: "TAB$i");
}),
),
),
TabBarView(
controller: _tabController,
children: List<Widget>.generate(_tabCount, (int i) {
return Text('line $i');
}),
),
],
),
);
}
}
而官方演示则使用以下这种结构
DefaultTabController
NestedScrollView
headerSliverBuilder
SliverOverlapAbsorber
handle
SliverAppBar
TabBarView
CustomScrollView
SliverOverlapInjector
handle
SliverPadding