[Flutter]ページ切り替えBottomNavigationBar()
pubspec.yaml
name: listview
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.0
flutter_hooks: ^0.14.0
hooks_riverpod: ^0.11.1
state_notifier: ^0.6.0
freezed_annotation: ^0.12.0
dev_dependencies:
flutter_test:
sdk: flutter
freezed: ^0.12.1
build_runner: ^1.10.1
flutter:
uses-material-design: true
main.dart
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:listview/widget/home.dart';
void main() {
runApp(
ProviderScope(
observers: [Logger()],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
// logger for riverpod
class Logger extends ProviderObserver {
@override
void didUpdateProvider(ProviderBase provider, Object newValue) {
print('''{
"provider": "${provider.name ?? provider.runtimeType}",
"newValue": "$newValue"
}''');
}
}
home.dart
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter/foundation.dart'; // *.freezed.dartで必要なのでimportしておく
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:listview/widget/list.dart';
part 'home.freezed.dart';
@freezed
abstract class HomeState with _$HomeState {
const factory HomeState({
@Default(0) int page,
}) = _HomeState;
}
final homeStateProvider = StateNotifierProvider((_) => HomeStateProvider());
class HomeStateProvider extends StateNotifier<HomeState> {
HomeStateProvider() : super(const HomeState());
void initState() {}
void dispose() {}
void onItemTapped(int index, PageController pageController) {
pageController.animateToPage(index,
duration: const Duration(milliseconds: 300), curve: Curves.ease);
}
void onPageChanged(int index) {
state = state.copyWith(page: index);
}
}
class MyHomePage extends HookWidget {
final items = List.generate(10, (index) => 'Item: $index');
final _pageController = PageController();
@override
Widget build(BuildContext context) {
final hsp = useProvider(homeStateProvider);
final homeState = useProvider(homeStateProvider.state);
return Scaffold(
appBar: AppBar(
title: Text('Dev'),
),
body: PageView(
controller: _pageController,
onPageChanged: hsp.onPageChanged,
children: [
MyList1(),
MyList2(),
MyList3(),
],
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '1',
),
BottomNavigationBarItem(
icon: Icon(Icons.youtube_searched_for_rounded),
label: '2',
),
BottomNavigationBarItem(
icon: Icon(Icons.animation),
label: '3',
),
],
currentIndex: homeState.page,
fixedColor: Colors.pink[300],
iconSize: 24,
// showSelectedLabels: true,
showUnselectedLabels: true,
unselectedItemColor: Colors.grey,
onTap: (index) {
hsp.onItemTapped(index, _pageController);
},
),
);
}
}
list.dart
import 'package:flutter/material.dart';
class MyList1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: buildBasicListView(),
),
);
}
Widget buildBasicListView() => ListView(
children: [
ListTile(
leading: Icon(Icons.arrow_forward_ios),
title: Text('list1'),
subtitle: Text('sublist1'),
trailing: Icon(Icons.star, color: Colors.orange),
),
ListTile(
leading: Icon(Icons.arrow_forward_ios),
title: Text('list2'),
subtitle: Text('sublist2'),
trailing: Icon(Icons.mood, color: Colors.blue),
),
ListTile(
leading: Icon(Icons.arrow_forward_ios),
title: Text('list3'),
subtitle: Text('sublist3'),
trailing: Icon(Icons.star, color: Colors.black),
),
ListTile(
leading: Icon(Icons.delete_forever, color: Colors.red),
title: Text('Delete'),
onTap: () {
print('Deleted');
}),
],
);
}
class MyList2 extends StatelessWidget {
final items = List.generate(10, (index) => 'Item: $index');
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: buildBasicListView(context),
),
);
}
Widget buildBasicListView(context) => ListView.separated(
separatorBuilder: (context, index) => Divider(color: Colors.black),
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(
title: Text(item),
);
},
);
}
class MyList3 extends StatelessWidget {
final items = List.generate(10, (index) => 'Item: $index');
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 10,
child: buildBasicListView(context),
),
);
}
Widget buildBasicListView(context) => ListView.separated(
padding: EdgeInsets.all(16),
scrollDirection: Axis.horizontal,
separatorBuilder: (context, index) => Divider(),
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Container(
alignment: Alignment.center,
margin: EdgeInsets.only(right: 16),
child: Text(item),
);
},
);
}