Repository navigation
RefreshIndicator syncs scrollposition across tabs when using TabbarView with AutomaticKeepAliveClientMixin inside NestedScrollView #62833
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.found in release: 3.3Found to occur in 3.3Found to occur in 3.3found in release: 3.7Found to occur in 3.7Found to occur in 3.7frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packages
Description
Use doc sample code for NestedScrollView , but have many problem.
- If you don't set SliderAppBar's expandedHeight, listview inside tabbarview can't scroll vertical.
- so I comment SliverOverlapAbsorber and SliverOverlapInjector code and can scroll vertical,
- but for retain each page inside tabbarview, I use AutomaticKeepAliveClientMixin and wantKeepAlive set to true,
- every page have a RefreshIndicator , when swip to refresh one page, other all page trigger onRefresh and show refresh progress at the same time and also all page scroll position all sync to the same position.
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> _tabs = [
"AAA",
"BBB",
"CCC",
"DDD",
"EEE",
"FFF",
];
@override
Widget build(BuildContext context) {
return 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),
// sliver:
SliverAppBar(
title: const Text('Books'), // This is the title in the app bar.
pinned: true,
floating: false,
snap: false,
// The "forceElevated" property causes the SliverAppBar to show
// a shadow. The "innerBoxIsScrolled" parameter is true when the
// inner scroll view is scrolled beyond its "zero" point, i.e.
// when it appears to be scrolled below the SliverAppBar.
// Without this, there are cases where the shadow would appear
// or not appear inappropriately, because the SliverAppBar is
// not actually aware of the precise position of the inner
// scroll views.
forceElevated: innerBoxIsScrolled,
bottom: TabBar(
isScrollable: true,
// 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 RefreshIndicator(child: 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(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: TabPage(),
),
],
), onRefresh: () => Future.delayed(Duration(seconds: 5)));
},
),
);
}).toList(),
),
),
);
}
}
class TabPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _TabPageState();
}
}
class _TabPageState extends State<TabPage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return SliverFixedExtentList(
// The items in this example are fixed to 48 pixels
// high. This matches the Material Design spec for
// ListTile widgets.
itemExtent: 48.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
// This builder is called for each child.
// In this example, we just number each list item.
return Material(child: ListTile(
title: Text('Item $index'),
));
},
// 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,
),
);
}
}
```shell
D:\flutter-projects\my_flutter_app>flutter doctor -v
[√] Flutter (Channel stable, v1.17.5, on Microsoft Windows [Version 10.0.18363.959], locale zh-CN)
• Flutter version 1.17.5 at D:\flutter
• Framework revision 8af6b2f038 (5 weeks ago), 2020-06-30 12:53:55 -0700
• Engine revision ee76268252
• Dart version 2.8.4
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at D:\Android\Sdk
• Platform android-29, build-tools 29.0.3
• ANDROID_HOME = D:\Android\Sdk
• Java binary at: D:\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
[√] Android Studio (version 4.0)
• Android Studio at D:\Android\Android Studio
• Flutter plugin version 48.0.2
• Dart plugin version 193.7361
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
[√] Connected device (1 available)
• SM G973U1 • R38M202PE2A • android-arm64 • Android 10 (API 29)
• No issues found!
D:\flutter-projects\my_flutter_app>Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.found in release: 3.3Found to occur in 3.3Found to occur in 3.3found in release: 3.7Found to occur in 3.7Found to occur in 3.7frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packages
Activity
z759341385 commentedon Aug 4, 2020
you can try to use this packge
https://pub.dev/packages/extended_nested_scroll_view#extendednestedscrollview
progratient commentedon Aug 4, 2020
Unfortunately, it seems does not solve these problems, am I right ?
[-]NestedScrollView + TabBarView + RefreshIndicator bug[/-][+]RefreshIndicator has issues when using TabbarView with AutomaticKeepAliveClientMixin inside NestedScrollView[/+]TahaTesser commentedon Aug 4, 2020
Code Sample
flutter doctor -v
ChihchengHsieh commentedon Nov 10, 2020
Any solution or workaround at this moment?
gabrielCuringa commentedon Jan 7, 2021
There is this post on StackOverflow which is two years old and doesn't seem to fix the problem... https://stackoverflow.com/questions/52264270/refreshindicator-with-nestedscrollview
ingmferrer commentedon Jan 17, 2021
Bump this
lanrehnics commentedon Jan 27, 2021
Any fix for this ?
azazadev commentedon May 15, 2021
any update ?
TomJoe2021 commentedon May 21, 2021
anyone?
9 remaining items
kishan-dhankecha commentedon Nov 21, 2022
Any Update?
icodeyou commentedon Nov 22, 2022
Any Update?
Khurshidddbek commentedon Dec 5, 2022
Developers we need an update.
Ra3wej commentedon Jan 2, 2023
setting
primary=falseof the tab that has the refresh indicator fixed the problem for me.
maybe you can set all the tab`s primary attribute that you have to false ?
maheshj01 commentedon Jan 10, 2023
Reproducible on stable 3.3 and master 3.7
code sample
flutter doctor -v (mac)
[-]RefreshIndicator has issues when using TabbarView with AutomaticKeepAliveClientMixin inside NestedScrollView[/-][+]RefreshIndicator syncs scrollposition across tabs when using TabbarView with AutomaticKeepAliveClientMixin inside NestedScrollView[/+]Piinks commentedon May 30, 2023
Referring to OP here:
This should be fixed by #127718
The root of this issue is #40740, so I am going to close this issue to refer there for updates, we try to consolidate dupes to focus everything in one issue. Thanks for reporting and providing updates! Let's follow up over there. :)
Fix update drag error that made NestedScrollView un-scrollable (#127718)
github-actions commentedon Jun 13, 2023
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.