画面遷移を実装しよう
このページで学ぶこと
- Flutter でページ間を移動できる
- データを渡しながら画面遷移できる
- ボトムナビゲーションバーを実装できる
Flutter の画面遷移
Flutter では画面(Widget)を**スタック(積み重ね)**で管理します。
スタック
┌──────────────┐ ← 詳細ページ(push で追加)
│ 詳細ページ │
├──────────────┤
│ 一覧ページ │ ← 最初のページ
└──────────────┘
← (back ボタンで pop して前に戻る)やってみよう
ステップ1: 基本的なページ遷移
// lib/main.dart
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(home: HomePage());
}
}
// ホームページ
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ホーム')),
body: Center(
child: ElevatedButton(
onPressed: () {
// Navigator.push で次の画面に進む
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const DetailPage()),
);
},
child: const Text('詳細ページへ'),
),
),
);
}
}
// 詳細ページ
class DetailPage extends StatelessWidget {
const DetailPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('詳細')), // ← 自動的に戻るボタンが追加される
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context); // 前のページに戻る
},
child: const Text('戻る'),
),
),
);
}
}ステップ2: データを渡して遷移する
次のページにデータを渡すには、コンストラクタで渡します。
// データを受け取るページ
class UserDetailPage extends StatelessWidget {
final String userName;
final int userId;
const UserDetailPage({
super.key,
required this.userName,
required this.userId,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(userName)),
body: Center(
child: Text('ユーザーID: $userId'),
),
);
}
}
// 呼び出し側
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserDetailPage(
userName: '田中太郎',
userId: 1,
),
),
);
},
child: const Text('ユーザー詳細へ'),
)ステップ3: ボトムナビゲーションバー
複数のタブを切り替えるUIには BottomNavigationBar が便利です。
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int _selectedIndex = 0;
// 各タブに対応するページ
static const List<Widget> _pages = [
Center(child: Text('ホーム', style: TextStyle(fontSize: 24))),
Center(child: Text('検索', style: TextStyle(fontSize: 24))),
Center(child: Text('プロフィール', style: TextStyle(fontSize: 24))),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('My App')),
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: (index) {
setState(() {
_selectedIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'ホーム'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: '検索'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'プロフィール'),
],
),
);
}
}Named Routes(名前付きルート)
画面が増えてきたら、名前付きルートで管理すると整理しやすくなります。
// MaterialApp でルートを定義
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const HomePage(),
'/detail': (context) => const DetailPage(),
'/profile': (context) => const ProfilePage(),
},
)
// 遷移する
Navigator.pushNamed(context, '/detail');
// 戻る
Navigator.pop(context);確認しよう
-
Navigator.pushで次のページに遷移できた -
Navigator.popで前のページに戻れた - コンストラクタでデータを渡しながら遷移できた
-
BottomNavigationBarでタブ切り替えを実装できた
AIに聞いてみよう
「Flutterのgo_routerパッケージとは何ですか?Navigatorとの違いを教えてください」
次のステップ
Last updated on