Return the scroll to the top when pressing the BottomNavigationBar item with Flutter

shogo.yamada
2 min readMay 18, 2019

--

We will introduce an implementation that returns the scroll to the top when pressing the common BottomNavigation such as twitter.

The implementation method is easy.

1, to detect ButtomNavigation of the same element
2, to set the
scroll listener 3, to return the scroll to the top via the scroll listener

1, detect ButtomNavigation of the same element

We detect by touch event of BottomNavigation

void _selectedTab(int index) {
if (_currentTab == index) {
// ここにスクロールを戻す処理を書く
} else {
setState(() {
_currentTab = index;
});
}
}

2, set the scroll listener

First create an instance of ScrollController

final ScrollController _homeController = ScrollController();

Set Controller to the widget to be scrolled after creation.
Although this example sets Controller to CustomScrollView, it is the same for ListView and SingleChildScrollView.

body: CustomScrollView(
controller: widget._controller,
slivers: <Widget>[
SliverStaggeredGrid.countBuilder(
crossAxisCount: 2,
itemBuilder: (context, index) {
String name = index.toString();
return _itemWidget(index, "assets/$name.png");
},
staggeredTileBuilder: (int index) => const StaggeredTile.fit(1),
itemCount: 6,
),
],
),

3, scroll back to the top via the scroll listener

Next, the process of returning the scroll to the top is completed.

void _selectedTab(int index) {
if (_currentTab == index) {
_homeController.animateTo(
0.0,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 300),
);
setState(() {
_currentTab = index;
});
}
}

Supplement

If you are divided into different classes according to the state of BottomNavigationItem, it is better to declare ScrollController in the parent widget and pass it to the child widget.

class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> { int _currentTab = 0; final ScrollController _homeController = ScrollController(); @override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
_buildOffstage(0, Feed(_homeController)), ← 渡す
_buildOffstage(1, MyPage(_myPageController)),  ← 渡す
],
),
bottomNavigationBar: FABBottomAppBar(
color: Colors.grey,
selectedColor: Colors.black,
onTabSelected: _selectedTab,
items: [
FABBottomAppBarItem(iconData: Icons.home, text: ""),
FABBottomAppBarItem(iconData: Icons.person_outline, text: ""),
],
)
);
}
Widget _buildOffstage(int index, Widget page) {
return Offstage(
offstage: index != _currentTab,
child: new TickerMode(
enabled: index == _currentTab,
child: page,
),
);
}
void _selectedTab(int index) {
if (_currentTab == index) {
if (index == 0) {
_homeController.animateTo(
0.0,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 300),
);
} else {
_myPageController.animateTo(
0.0,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 300),
);
}
} else {
setState(() {
_currentTab = index;
});
}
}
}

--

--

shogo.yamada
shogo.yamada

Written by shogo.yamada

普段はエンジニアやってます👨‍💻 自分の資産運用の記録として書いてり、プライベートなことを書いていきます。

No responses yet