-
-
Save IkhwanSI13/eb09a588096db4c88f96ad9f2faf91d1 to your computer and use it in GitHub Desktop.
import 'package:cartenz_djp/style/colors.dart'; | |
import 'package:cartenz_djp/widget/override/customTabs.dart' as Tabs; | |
import 'package:flutter/material.dart'; | |
class ExampleWidget extends StatefulWidget { | |
@override | |
State<StatefulWidget> createState() => ExampleState(); | |
} | |
class ExampleState extends State<ExampleWidget> { | |
onLoadMore() { | |
//Load More, do something | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
backgroundColor: ColorWhite, | |
body: Column( | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
Expanded( | |
child: Builder(builder: (BuildContext context) { | |
return NestedScrollView( | |
//controller: scrollController, | |
headerSliverBuilder: | |
(BuildContext context, bool innerBoxIsScrolled) { | |
return <Widget>[ | |
SliverAppBar( | |
bottom: getTabHeader(), | |
) | |
]; | |
}, body: Builder(builder: (BuildContext context) { | |
return Stack(children: <Widget>[ | |
getTabBody(), | |
]); | |
})); | |
}), | |
) | |
], | |
), | |
); | |
} | |
Widget getTabHeader() { | |
return Tabs.TabBar(tabs: [ | |
Tabs.Tab(child: Text("Tab 1")), | |
Tabs.Tab(child: Text("Tab 2")), | |
Tabs.Tab(child: Text("Tab 3")), | |
]); | |
} | |
Widget getTabBody() { | |
return Column( | |
children: <Widget>[ | |
Expanded( | |
child: Tabs.TabBarView(children: [ | |
Container( | |
child: | |
//Solved with this | |
NotificationListener<ScrollNotification>( | |
child: MediaQuery.removePadding( | |
context: context, | |
removeTop: true, | |
child: ListView.builder( | |
shrinkWrap: true, | |
itemCount: 3, | |
physics: NeverScrollableScrollPhysics(), | |
itemBuilder: (BuildContext context, int index) { | |
return Container(); | |
})), | |
onNotification: (ScrollNotification scrollInfo) { | |
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) { | |
//load more here | |
onLoadMore(); | |
} | |
return false; | |
}, | |
); | |
Container(child: Container()), | |
Container(child: Container()) | |
])) | |
], | |
); | |
} | |
} |
This does not trigger NestedScrollView. SliverAppbar does not get collapsed
yeah, with the new flutter version make the SliverAppBar do not get collapsed.
This does not trigger NestedScrollView. SliverAppbar does not get collapsed
In case someone stumbles upon this, you can wrap your inner ListView with a NotificationListener() and check if the Notification is an OverScrollNotification. This is how I got around the issue. As opposed to the solution described above (so no SingleChildScrollView and no Scrollcontroller inside your ListView)
I think, I tried this too, but not work. Maybe it runs correctly now.
btw, thanks for the answer
This does not trigger NestedScrollView. SliverAppbar does not get collapsed
In case someone stumbles upon this, you can wrap your inner ListView with a NotificationListener() and check if the Notification is an OverScrollNotification. This is how I got around the issue. As opposed to the solution described above (so no SingleChildScrollView and no Scrollcontroller inside your ListView)
I tried it, and it's work. thanks, dude
@IkhwanSI13 Please can you share your code i have the same issue.
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(
color: Color(0xFF6991C7),
),
title: Text(
"Search",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 18.0,
color: Colors.black54,
fontFamily: "Gotik"),
),
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0.0,
),
body: SingleChildScrollView(
primary: false,
child: Container(
color: Colors.white,
padding: EdgeInsets.only(top: 15.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_textHello,
BlocListener<FilterBloc, FilterState>(
listener: (context, state) {
if (state is ErrorFilter) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(state.message),
),
);
}
},
child: BlocBuilder<FilterBloc, FilterState>(
// ignore: missing_return
builder: (context, state) {
if (state is InitialFilter) {
return buildInitialInput();
} else if (state is LoadingFilter) {
return buildLoading();
} else if (state is LoadedFilter) {
if (state.products.isEmpty) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ProductInputField(),
SizedBox(height: 30.0),
Center(child: Text('No content'))
],
);
}
return Column(
children: <Widget>[
ProductInputField(),
SizedBox(height: 30.0),
NotificationListener<ScrollNotification>(
onNotification: (notification) => _onScrollNotification(notification, state),
child: GridView.builder(
physics: ScrollPhysics(),
itemCount: state.products.length,
primary: false,
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: 0.605,
crossAxisCount: 2,
),
itemBuilder: (context, pos) {
return ProductWidget(product: state.products[pos]);
},
),
),
],
);
} else if (state is ErrorFilter) {
return buildInitialInput();
}
},
),
),
],
)
),
),
);
}
bool _onScrollNotification(ScrollNotification notif, LoadedFilter state) {
if (notif is ScrollEndNotification && notif.metrics.pixels == notif.metrics.maxScrollExtent) {
context.bloc<FilterBloc>().add(LoadMoreFilter(products: state.products, productName: 'a', stateName: ''));
}
return false;
}
@IkhwanSI13 Please can you share your code i have the same issue.
return Scaffold( appBar: AppBar( iconTheme: IconThemeData( color: Color(0xFF6991C7), ), title: Text( "Search", style: TextStyle( fontWeight: FontWeight.w700, fontSize: 18.0, color: Colors.black54, fontFamily: "Gotik"), ), centerTitle: true, backgroundColor: Colors.white, elevation: 0.0, ), body: SingleChildScrollView( primary: false, child: Container( color: Colors.white, padding: EdgeInsets.only(top: 15.0, bottom: 30.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ _textHello, BlocListener<FilterBloc, FilterState>( listener: (context, state) { if (state is ErrorFilter) { Scaffold.of(context).showSnackBar( SnackBar( content: Text(state.message), ), ); } }, child: BlocBuilder<FilterBloc, FilterState>( // ignore: missing_return builder: (context, state) { if (state is InitialFilter) { return buildInitialInput(); } else if (state is LoadingFilter) { return buildLoading(); } else if (state is LoadedFilter) { if (state.products.isEmpty) { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ ProductInputField(), SizedBox(height: 30.0), Center(child: Text('No content')) ], ); } return Column( children: <Widget>[ ProductInputField(), SizedBox(height: 30.0), NotificationListener<ScrollNotification>( onNotification: (notification) => _onScrollNotification(notification, state), child: GridView.builder( physics: ScrollPhysics(), itemCount: state.products.length, primary: false, shrinkWrap: true, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisSpacing: 10.0, mainAxisSpacing: 10.0, childAspectRatio: 0.605, crossAxisCount: 2, ), itemBuilder: (context, pos) { return ProductWidget(product: state.products[pos]); }, ), ), ], ); } else if (state is ErrorFilter) { return buildInitialInput(); } }, ), ), ], ) ), ), ); } bool _onScrollNotification(ScrollNotification notif, LoadedFilter state) { if (notif is ScrollEndNotification && notif.metrics.pixels == notif.metrics.maxScrollExtent) { context.bloc<FilterBloc>().add(LoadMoreFilter(products: state.products, productName: 'a', stateName: '')); } return false; }
just check my code above. I updated it
@IkhwanSI13 Thanks for replying, Notifications Listener not working with multi ListView like my case, So i resolved this problem by add listener function instead of Notifications Listener.
Thanks for the code.It is working well 👍
In case someone stumbles upon this, you can wrap your inner ListView with a NotificationListener() and check if the Notification is an OverScrollNotification. This is how I got around the issue. As opposed to the solution described above (so no SingleChildScrollView and no Scrollcontroller inside your ListView)