Reputation: 21
In my project I have a project where I only want to set the visibility of an action button
if the screen is scrolled all the way up.
The code that I have right now works fine but it will trigger the code as soon as the screen begins to scroll up - and it is really not what I want.
So how can I fix this ?
Below is my code as on demand
class AccountPage extends StatefulWidget with NavigationStates {
@override
_AccountPage createState() => _AccountPage();
}
class _AccountPage extends State<AccountPage> {
String searchQuery = '';
ScrollController _controller;
bool sliverActionsHidden = true;
// Tracking search query.
void _updateSearchQuery(String query) {
setState(
() {
searchQuery = query;
},
);
}
// Listening for user scroll on screen.
void _scrollListener() {
if (_controller.offset <= _controller.position.minScrollExtent &&
!_controller.position.outOfRange) {
setState(() {
sliverActionsHidden = false;
print('Reach the top');
});
}
else {
setState(() {
sliverActionsHidden = true;
print('Reach the bottom');
});
}
}
@override
void initState() {
_controller = ScrollController();
_controller.addListener(_scrollListener);
super.initState();
}
@override
Widget build(BuildContext context) {
/* Action IconButtons ----------------------------------------------- */
final actionButtons = <Widget>[
IconButton(
icon: Icon(Icons.filter_list),
onPressed: () {
print('Filter');
},
),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {
print('More Settings');
},
),
];
/* Material Appbar ----------------------------------------------- */
final PreferredSizeWidget appBar = SearchBar(
canSearch: true,
query: searchQuery,
searchQuery: (value) {
_updateSearchQuery(value);
print("Listening for search query : $value");
},
// Action Icons
actions: actionButtons,
);
/* Sliver Appbar ----------------------------------------------- */
final sliverAppBar = SliverAppBar(
pinned: true,
expandedHeight: MediaQuery.of(context).size.height * 0.2,
backgroundColor: Theme.of(context).primaryColor,
flexibleSpace: FlexibleSpaceBar(
// Searchbar
background: Column(
children: <Widget>[
appBar,
],
),
// Page Title
title: Text(
AppStrings.accountTitle,
style: Theme.of(context).textTheme.title.copyWith(
color: CustomColors().novaWhite,
),
),
),
// Action Buttons
actions: sliverActionsHidden ? actionButtons : <Widget>[],
);
/* Page Content ----------------------------------------------- */
final bodyContent = SafeArea(
bottom: false,
child: CustomScrollView(
controller: _controller,
slivers: <Widget>[
sliverAppBar,
SliverToBoxAdapter(
child: Container(
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.all(Constants.paddingXY_32),
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
// Page content begins here...
child: Text(searchQuery.toString()),
),
),
],
),
);
/* Scaffold ----------------------------------------------- */
return Scaffold(
body: bodyContent,
backgroundColor: Theme.of(context).primaryColor,
);
}
}
Upvotes: 2
Views: 2014
Reputation: 2215
You can check if the maxScrollExtent
value of the scroll position is reached :
void _scrollListener() {
if (_controller.offset == _controller.position.maxScrollExtent) {
setState(() {
sliverActionsHidden = true;
print('Reach the top');
});
} else {
setState(() {
sliverActionsHidden = false;
print('Reach the bottom');
});
}
}
Upvotes: 1