どうも、ちょげ(@chogetarou)です。
BottomNavigationBarの状態を画面の切り替えでリセットされないようにする方法を紹介します。
方法

BottomNavigationBarの状態を保持しておくには、IndexedStackを使います。
まず、Scaffoldの引数「body」にIndexedStackを指定します。
次に、IndexedStackの引数「index」に、BottomNavigationBarの引数「currentIndex」に指定しているものと同じものを指定します。
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
),
bottomNavigationBar: BottomNavigationBar(
items: [
・・・
],
currentIndex: _currentIndex,
onTap: _onTap,
),
);
}
最後に、IndexedStackの引数「children」に切り替える画面をリストで指定します。
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: [
Page1(),
Page2(),
Page3(),
・・・
],
),
bottomNavigationBar: BottomNavigationBar(
items: [
・・・
],
currentIndex: _currentIndex,
onTap: _onTap,
),
);
}
これでBottomNavigationBarの状態を保持しておくことが出来るようになります。
使用例
以下は、使用例です。
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
var _currentIndex = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: [
Page1(),
Container(
child: Text('Home'),
alignment: Alignment.center,
color: Colors.yellow,
),
Container(
child: Text('Favorite'),
alignment: Alignment.center,
color: Colors.pink.withOpacity(0.3),
),
],
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.pages),
label: 'Page1',
),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite),
label: 'Favorite',
),
],
currentIndex: _currentIndex,
onTap: _onTap,
),
);
}
void _onTap(int index) {
setState(() {
_currentIndex = index;
});
}
}
class Page1 extends StatefulWidget {
Page1({Key? key}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
var _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'$_count',
style: TextStyle(fontSize: 200),
),
TextButton(
onPressed: () {
setState(() {
_count++;
});
},
child: Text('Increment'),
),
],
),
),
);
}
}
まとめ
BottomNavigationBarの状態を保持しておくには、IndexedStackを使います。
コメント