the flutter document show a demo for SliverAppBar
+ TabBar
+ TabBarView with ListView
use NestedScrollView
, and it's a bit complex, so I wonder is there a simply and clear way to implement it. I tried this:
CustomScrollView
slivers:
SliverAPPBar
bottom: TabBar
TabBarView
children: MyWidget(list or plain widget)
got error:
flutter: The following assertion was thrown building Scrollable(axisDirection: right, physics:
flutter: A RenderViewport expected a child of type RenderSliver but received a child of type _RenderExcludableScrollSemantics.
flutter: RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.
and
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.
HERE IS MY CODE:
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');
}),
),
],
),
);
}
}
and for the official demo, it use struct like this
DefaultTabController
NestedScrollView
headerSliverBuilder
SliverOverlapAbsorber
handle
SliverAppBar
TabBarView
CustomScrollView
SliverOverlapInjector
handle
SliverPadding
Here is the minimal code to get SliverAppBar up and running: return Scaffold( //1 body: CustomScrollView( slivers: <Widget>[ //2 SliverAppBar( expandedHeight: 250.0, flexibleSpace: FlexibleSpaceBar( title: Text('Goa', textScaleFactor: 1), background: Image. asset( 'assets/images/beach. png', fit: BoxFit.
Use NestedScrollView
, here is the working code.
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.call), text: "Call"),
Tab(icon: Icon(Icons.message), text: "Message"),
],
),
),
];
},
body: TabBarView(
children: [
CallPage(),
MessagePage(),
],
),
),
),
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With