使用 Riverpod 的 Flutter 导航栏
Flutter navigationBar with Riverpod
我试图管理我的状态,但我真的做不到。我想学习如何使用 riverpod 包在管理页面底部创建一个导航栏。
我设法管理我们点击的页面,但我不知道如何根据所选按钮 return 正确的寻呼机
Main.dart :
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:app/ui/screens/my_app/my_app_screen.dart';
void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}
NavigationBarScreen.dart:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
final provider = StateNotifierProvider((ref) => NavigationNotifier());
class NavigationBarScreen extends HookWidget
{
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body : Container(
margin: EdgeInsets.only(left : 8, right : 8, bottom: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20), topLeft: Radius.circular(20)),
boxShadow: [
BoxShadow(color: AppColors.colorShadowLight, spreadRadius: 0, blurRadius: 10),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(50.0),
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: AppColors.colorBgDark,
fixedColor: AppColors.colorContrastOrange,
unselectedItemColor: AppColors.colorFontLight2,
currentIndex: 0,
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: context.read(provider).selectPage,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
),
),
);
}
}
NavigationNotifier.dart:
import 'package:hooks_riverpod/hooks_riverpod.dart';
enum NavigationBarEvent { HOME, PROFIL}
class NavigationNotifier extends StateNotifier<PageModel> {
NavigationNotifier() : super(defaultPage);
static const defaultPage = PageModel(NavigationBarEvent.HOME);
void selectPage(int i){
switch (i) {
case 0:
state = PageModel(NavigationBarEvent.HOME);
break;
case 1:
state = PageModel(NavigationBarEvent.PROFIL);
break;
}
}
}
class PageModel {
const PageModel(this.page);
final NavigationBarEvent page;
}
看来您已经实现了用户单击底部栏时修改状态的所有逻辑。
唯一剩下的就是监听状态(可能在您的脚手架中),并决定显示哪个页面。
一种可能是这样写:
class NavigationBarScreen extends HookWidget {
@override
Widget build(BuildContext context) {
final pageModel = useProvider(provider.state);
Widget body;
switch (pageModel.page) {
case NavigationBarEvent.HOME:
body = Home();
break;
case NavigationBarEvent.PROFIL:
body: Profile();
break;
}
return Scaffold(
body: body,
bottomBar: ...
);
}
}
更新于 2022 年 1 月 27 日。
https://pub.dev/packages/flutter_riverpod/versions/1.0.3
这是另一种对我有用的方法,如果你也想在拖动时控制“页面视图 + 底部导航栏”:
class Index extends StateNotifier<int> {
Index() : super(0);
set value(int index) => state = index;
}
final indexProvider = StateNotifierProvider((ref) => Index());
class Home extends ConsumerWidget {
static const route = '/home';
const Home({Key? key}) : super(key: key);
final List<Widget> fragments = const [
Text('Page 1'),
Text('Page 2'),
Text('Page 3')
];
final List<BottomNavigationBarItem> navItems = const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.camera), label: 'Camera'),
BottomNavigationBarItem(icon: Icon(Icons.edit), label: 'Edit'),
];
final Text title = const Text('My App');
@override
Widget build(BuildContext context, WidgetRef ref) {
final PageController controller = PageController();
final int menuIndex = ref.watch(indexProvider) as int;
return Scaffold(
appBar: AppBar(title: title, actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.list))
]),
body: PageView(
controller: controller,
children: fragments,
onPageChanged: (i) => ref.read(indexProvider.notifier).value = i),
bottomNavigationBar: BottomNavigationBar(
items: navItems,
currentIndex: menuIndex,
onTap: (i) {
ref.read(indexProvider.notifier).value = i;
controller.animateToPage(i,
duration: const Duration(seconds: 1), curve: Curves.easeInOut);
}),
);
}
}
我试图管理我的状态,但我真的做不到。我想学习如何使用 riverpod 包在管理页面底部创建一个导航栏。
我设法管理我们点击的页面,但我不知道如何根据所选按钮 return 正确的寻呼机
Main.dart :
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:app/ui/screens/my_app/my_app_screen.dart';
void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}
NavigationBarScreen.dart:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
final provider = StateNotifierProvider((ref) => NavigationNotifier());
class NavigationBarScreen extends HookWidget
{
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body : Container(
margin: EdgeInsets.only(left : 8, right : 8, bottom: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20), topLeft: Radius.circular(20)),
boxShadow: [
BoxShadow(color: AppColors.colorShadowLight, spreadRadius: 0, blurRadius: 10),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(50.0),
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: AppColors.colorBgDark,
fixedColor: AppColors.colorContrastOrange,
unselectedItemColor: AppColors.colorFontLight2,
currentIndex: 0,
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: context.read(provider).selectPage,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
),
),
);
}
}
NavigationNotifier.dart:
import 'package:hooks_riverpod/hooks_riverpod.dart';
enum NavigationBarEvent { HOME, PROFIL}
class NavigationNotifier extends StateNotifier<PageModel> {
NavigationNotifier() : super(defaultPage);
static const defaultPage = PageModel(NavigationBarEvent.HOME);
void selectPage(int i){
switch (i) {
case 0:
state = PageModel(NavigationBarEvent.HOME);
break;
case 1:
state = PageModel(NavigationBarEvent.PROFIL);
break;
}
}
}
class PageModel {
const PageModel(this.page);
final NavigationBarEvent page;
}
看来您已经实现了用户单击底部栏时修改状态的所有逻辑。
唯一剩下的就是监听状态(可能在您的脚手架中),并决定显示哪个页面。
一种可能是这样写:
class NavigationBarScreen extends HookWidget {
@override
Widget build(BuildContext context) {
final pageModel = useProvider(provider.state);
Widget body;
switch (pageModel.page) {
case NavigationBarEvent.HOME:
body = Home();
break;
case NavigationBarEvent.PROFIL:
body: Profile();
break;
}
return Scaffold(
body: body,
bottomBar: ...
);
}
}
更新于 2022 年 1 月 27 日。 https://pub.dev/packages/flutter_riverpod/versions/1.0.3
这是另一种对我有用的方法,如果你也想在拖动时控制“页面视图 + 底部导航栏”:
class Index extends StateNotifier<int> {
Index() : super(0);
set value(int index) => state = index;
}
final indexProvider = StateNotifierProvider((ref) => Index());
class Home extends ConsumerWidget {
static const route = '/home';
const Home({Key? key}) : super(key: key);
final List<Widget> fragments = const [
Text('Page 1'),
Text('Page 2'),
Text('Page 3')
];
final List<BottomNavigationBarItem> navItems = const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.camera), label: 'Camera'),
BottomNavigationBarItem(icon: Icon(Icons.edit), label: 'Edit'),
];
final Text title = const Text('My App');
@override
Widget build(BuildContext context, WidgetRef ref) {
final PageController controller = PageController();
final int menuIndex = ref.watch(indexProvider) as int;
return Scaffold(
appBar: AppBar(title: title, actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.list))
]),
body: PageView(
controller: controller,
children: fragments,
onPageChanged: (i) => ref.read(indexProvider.notifier).value = i),
bottomNavigationBar: BottomNavigationBar(
items: navItems,
currentIndex: menuIndex,
onTap: (i) {
ref.read(indexProvider.notifier).value = i;
controller.animateToPage(i,
duration: const Duration(seconds: 1), curve: Curves.easeInOut);
}),
);
}
}