始めに
こんな感じでスワイプとタブのタップの両方でページを切り替えられるものを作ります
https://github.com/shotaro427/page_animation_sample
こちらに実際に動くコードがあるので、もし分かりずらかったりしたらこちらもご覧ください
環境
Flutter: 1.20.0
channel: stable
Dart: 2.9.1
BottomNavigationBarを作る
UIを作成
まずは見た目を作成します
@override
Widget build(BuildContext context) {
return Scaffold(
// ~~~ 略 ~~~
// ~~~以下追加~~~
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('ホーム'),
),
BottomNavigationBarItem(
icon: Icon(Icons.pages),
title: Text('コンテンツ'),
),
],
),
);
}
これでホットリロードすると、こんな感じの見た目になるはずです。
けど、まだボタンを押しても何にも起こらないと思うので、まずは「コンテンツ」を押したらアクティブが変わるようにしましょう
アイコンの動的化
class _MyHomePageState extends State<MyHomePage> {
// ~~~ 略 ~~~
// ~~~ 以下追加 ~~~
int _currentIndex = 0;
void onItemTapped(int index) {
setState(() {
_currentIndex = index;
});
}
// ~~~ ここまで ~~~
// ~~~ 略 ~~~
@override
Widget build(BuildContext context) {
return Scaffold(
// ~~~ 略 ~~~
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('ホーム'),
),
BottomNavigationBarItem(
icon: Icon(Icons.pages),
title: Text('コンテンツ'),
),
],
currentIndex: _currentIndex, // 追加!!
onTap: onItemTapped, // 追加!!
),
);
}
}
これでタブバーのアイコンを選択すると色が変わるようになったと思います!
では、次はページを作ってタブを押すとページが切り替わる部分を作っていきます
PageViewを作る
PageViewを使うと、スワイプなどのアクションでアニメーション付きのページ切り替えを実装することができます
中身の作成
ページ切り替えをするコンテンツのWidgetを作ります
ここでは単純にWidgetの配列を定義するだけです
class _MyHomePageState extends State<MyHomePage> {
// ~~~ 略 ~~~
// ~~~~ 以下追加 ~~~
static const List<Widget> _widgets = <Widget>[
Center(
child: Text(
'This Page is HOME',
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
'This Page is Contents',
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
];
// ~~~ ここまで ~~~
// ~~~ 略 ~~~
}
次にScaffoldのBody部分にPageViewを実装していきます
@override
Widget build(BuildContext context) {
return Scaffold(
// ~~~ 略 ~~~
// ~~~ 以下変更 ~~~
body: PageView(
children: _widgets,
onPageChanged: onItemTapped,
),
// ~~~ ここまで ~~~
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('ホーム'),
),
BottomNavigationBarItem(
icon: Icon(Icons.pages),
title: Text('コンテンツ'),
),
],
currentIndex: _currentIndex,
onTap: onItemTapped,
),
);
}
これでリロードをすると、スワイプでページが切り替わるようになったと思います
しかし、タブのアイコンでのページ切り替えをまだ作っていないので、次でその部分を作っていきます!
PageControllerを作る
先ほど変更したPageViewに自作のPageControllerを適用させて、タブをアイコンを押した時にページの切り替えを行うようにしていきましょう
class _MyHomePageState extends State<MyHomePage> {
// ~~~ 略 ~~~
// ~~~ 追加 ~~~
final PageController _pageController = PageController();
// ~~~ ここまで ~~~
void onItemTapped(int index) {
// ~~~ 追加 ~~~
_pageController.animateToPage(index,
duration: const Duration(milliseconds: 100), curve: Curves.easeIn);
// ~~~ ここまで ~~~
setState(() {
_currentIndex = index;
});
}
// ~~~ 略 ~~~
@override
Widget build(BuildContext context) {
return Scaffold(
// ~~~ 略 ~~~
body: PageView(
children: _widgets,
onPageChanged: onItemTapped,
// ~~~~ 以下追加 ~~~
controller: _pageController,
),
// ~~~ 略 ~~~
);
}
}
新しくPageController
を定義して、それを先ほど作ったPageView
に適用。
そのコントローラーを通して、タブのアイコンがタップされた時にアニメーション付きでページ切り替えを行うという仕組みです
最後に
Flutterでアプリを作っていて、タブのページ遷移ってどうやるんだ?と思ったので色々調べてみました
もしお役に立ったなら幸いです!