[Flutter]ページ切り替えBottomNavigationBar()

画像1

画像2

画像3

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),
         );
       },
     );
}

この記事が気に入ったらサポートをしてみませんか?