I am currently working on a application which has both appbar and bottom navbar. I wanted the appbar and bottom navbar hide while the user scroll. I have two screens
- Navbar screen : Here the code for bottom navbar and appbar is written which consists where body is the UI shown to the user.
- ListView Screen: This is the UI which consists a list of data.
I wanted the output like this:
NavBar :
class MyNavBarr extends StatefulWidget {
const MyNavBarr({super.key});
@override
State<MyNavBarr> createState() => _MyNavBarrState();
}
class _MyNavBarrState extends State<MyNavBarr> {
int _selectedIndex = 0;
static const List<Widget> _widgetOptions = <Widget>[
LiistView(),
LiistView(),
LiistView(),
LiistView(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppBar"),
centerTitle: true,
),
body: _widgetOptions.elementAt(_selectedIndex),
bottomNavigationBar: SizedBox(
height: 65.0,
child: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(IconlyLight.image),
label: '',
),
BottomNavigationBarItem(
icon: Icon(IconlyLight.video),
label: '',
),
BottomNavigationBarItem(
icon: Icon(Icons.library_music_outlined),
label: '',
),
BottomNavigationBarItem(
icon: Icon(IconlyLight.profile),
label: '',
),
],
currentIndex: _selectedIndex,
showSelectedLabels: true,
showUnselectedLabels: false,
selectedFontSize: 0.0,
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,
),
),
);
}
}
ListView :
class LiistView extends StatefulWidget {
const LiistView({super.key});
@override
State<LiistView> createState() => _LiistViewState();
}
class _LiistViewState extends State<LiistView> {
final controller = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: 80,
itemBuilder: (context, index){
return const ListTile(
title: Text("Abcd"),
);
},
),
);
}
}
CodePudding user response:
The easiest way to do so is that,
ScrollController _hideButtonController;
bool _isVisible = true;
@override
void initState() {
super.initState();
_isVisible = true;
_hideButtonController = new ScrollController();
_hideButtonController.addListener(() {
print("listener");
if (_hideButtonController.position.userScrollDirection ==
ScrollDirection.reverse) {
setState(() {
_isVisible = false;
print("**** $_isVisible up");
});
}
if (_hideButtonController.position.userScrollDirection ==
ScrollDirection.forward) {
setState(() {
_isVisible = true;
print("**** $_isVisible down");
});
}
});
}
Wrap your bottom Nav bar with animated container same as below
AnimatedContainer(
duration: Duration(milliseconds: 200),
height: _isVisible ? 60 : 0.0,
child: BottomNavBarCode......,
),
Build your list view and app bar same as below
CustomScrollView(
controller: _hideButtonController,
slivers: <Widget>[
SliverAppBar(
expandedHeight: 150,
pinned: true, // กำหนดว่าจะให้ pin appbar ไว้บางส่วนไหม หรือ ให้หายไปหมด
floating: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
title: Text(widget._grassroot.name),
// title: Text('GRASSROOT ENGINEER'),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
//YOUR_LIST_VIEW_CODE,
childCount: exercises.length),
),
],
),
)
CodePudding user response:
You can add a listener to the scrollController. And then Update the UI based on the user scroll input.
Try something like below.
ScrollController scrollController = ScrollController();
@override
void initState() {
super.initState();
scrollController.addListener(_updateScrollController);
}
void _updateScrollController() async {
if (!mounted) {
return;
}
if (scrollController.position.pixels < -100) {
if (!showSearchbar) {
HapticFeedback.heavyImpact();
setState(() {
showSearchbar = true;
});
}
} else if (scrollController.position.pixels > 50) {
if (showSearchbar) {
HapticFeedback.heavyImpact();
setState(() {
showSearchbar = false;
});
}
}
}
CodePudding user response:
You can achieve this using the Hideable library.
Create a Scroll Controller
and pass it to the scrollable widget
final ScrollController scrollController = ScrollController();
ListView(
controller: scrollController,
...
)
Wrap your BottomNavigationBar
with Hideable
Hidable(
controller: scrollController,
wOpacity: true, // default
child: BottomNavigationBar(...),
)