Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save iRbouh/219a81b3f2e32c3ef725972b45627f2e to your computer and use it in GitHub Desktop.
Save iRbouh/219a81b3f2e32c3ef725972b45627f2e to your computer and use it in GitHub Desktop.
class NewsScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => _NewsScreenState();
}
class _NewsScreenState extends State<NewsScreen> {
final List<String> listItems = [];
final List<String> _tabs = <String>[
"Featured",
"Popular",
"Latest",
];
@override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
body: DefaultTabController(
length: _tabs.length, // This is the number of tabs.
child: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
// These are the slivers that show up in the "outer" scroll view.
return <Widget>[
SliverOverlapAbsorber(
// This widget takes the overlapping behavior of the SliverAppBar,
// and redirects it to the SliverOverlapInjector below. If it is
// missing, then it is possible for the nested "inner" scroll view
// below to end up under the SliverAppBar even when the inner
// scroll view thinks it has not been scrolled.
// This is not necessary if the "headerSliverBuilder" only builds
// widgets that do not overlap the next sliver.
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverSafeArea(
top: false,
sliver: SliverAppBar(
title: const Text('Books'),
floating: true,
pinned: true,
snap: false,
primary: true,
forceElevated: innerBoxIsScrolled,
bottom: TabBar(
// These are the widgets to put in each tab in the tab bar.
tabs: _tabs.map((String name) => Tab(text: name)).toList(),
),
),
),
),
];
},
body: TabBarView(
// These are the contents of the tab views, below the tabs.
children: _tabs.map((String name) {
return SafeArea(
top: false,
bottom: false,
child: Builder(
// This Builder is needed to provide a BuildContext that is "inside"
// the NestedScrollView, so that sliverOverlapAbsorberHandleFor() can
// find the NestedScrollView.
builder: (BuildContext context) {
return CustomScrollView(
// The "controller" and "primary" members should be left
// unset, so that the NestedScrollView can control this
// inner scroll view.
// If the "controller" property is set, then this scroll
// view will not be associated with the NestedScrollView.
// The PageStorageKey should be unique to this ScrollView;
// it allows the list to remember its scroll position when
// the tab view is not on the screen.
key: PageStorageKey<String>(name),
slivers: <Widget>[
SliverOverlapInjector(
// This is the flip side of the SliverOverlapAbsorber above.
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
),
SliverPadding(
padding: const EdgeInsets.all(8.0),
// In this example, the inner scroll view has
// fixed-height list items, hence the use of
// SliverFixedExtentList. However, one could use any
// sliver widget here, e.g. SliverList or SliverGrid.
sliver: SliverFixedExtentList(
// The items in this example are fixed to 48 pixels
// high. This matches the Material Design spec for
// ListTile widgets.
itemExtent: 60.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
// This builder is called for each child.
// In this example, we just number each list item.
return Container(
color: Color((math.Random().nextDouble() *
0xFFFFFF)
.toInt() <<
0)
.withOpacity(1.0));
},
// The childCount of the SliverChildBuilderDelegate
// specifies how many children this inner list
// has. In this example, each tab has a list of
// exactly 30 items, but this is arbitrary.
childCount: 30,
),
),
),
],
);
},
),
);
}).toList(),
),
),
),
),
);
}
}
@ninest
Copy link

ninest commented Mar 25, 2019

image

Is there anything that can be done to remove this white space above the list? I believe it is being created by the sliverOverlapAbsorberHandleFor.

@azuddin
Copy link

azuddin commented Sep 17, 2019

Also have another issue, when i scroll Latest tabbarview until top, all the scroll position for other tabbarview will be reset. How can i fix that?

@MartinJLee
Copy link

In case, someone looks for a demo of this https://dartpad.dev/4b3ed2ac8284bc6931b930c5c75b0d32

@Balajijangde
Copy link

I want to execute some code when internal CustomScrollview reaches its end but by defining a controller scrollview disconnects from outer scrollview and everything mess up

@varpa89
Copy link

varpa89 commented Mar 2, 2021

In case, someone looks for a demo of this https://dartpad.dev/4b3ed2ac8284bc6931b930c5c75b0d32

cool! reproduces even on web

@AmineLAHRIM
Copy link

Also have another issue, when i scroll Latest tabbarview until top, all the scroll position for other tabbarview will be reset. How can i fix that?

@DK070202
Copy link

DK070202 commented Dec 2, 2021

@ninest
Wrap this list view with MediaQuery.removePadding and pass context ,remove top to 'true'.
it did work for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment