Flutter Flitter riverpod小部件调用了两次
我正在努力学习颤振和Riverpod,并尝试使用干净的代码。我只是注意到我的小部件被调用了两次。如何避免不必要的操作 我的项目只是一个导航栏,根据我们单击的按钮加载视图 我的导航栏屏幕:Flutter Flitter riverpod小部件调用了两次,flutter,dart,riverpod,Flutter,Dart,Riverpod,我正在努力学习颤振和Riverpod,并尝试使用干净的代码。我只是注意到我的小部件被调用了两次。如何避免不必要的操作 我的项目只是一个导航栏,根据我们单击的按钮加载视图 我的导航栏屏幕: class NavigationBarScreen extends HookWidget { @override Widget build(BuildContext context) { print('build navigationScreen'); final _pageMode
class NavigationBarScreen extends HookWidget
{
@override
Widget build(BuildContext context) {
print('build navigationScreen');
final _pageModel = useProvider(navigationProvider.state);
return SafeArea(
child: Scaffold(
body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
bottomNavigationBar: 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: _pageModel.navigationIndexItem,
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: context.read(navigationProvider).selectPage,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
),
),
);
}
}
enum NavigationBarState
{
HOME, PROFIL
}
class NavigationNotifier extends StateNotifier<NavigationBarModel>
{
NavigationNotifier() : super(_initialPage);
static const int _initialIndex = 0;
static const NavigationBarState _initialState = NavigationBarState.HOME;
static const _initialPage = NavigationBarModel(pageState : _initialState, navigationIndexItem : _initialIndex);
void selectPage(int i)
{
switch (i)
{
case 0:
state = NavigationBarModel(pageState : NavigationBarState.HOME, navigationIndexItem : i);
break;
case 1:
state = NavigationBarModel(pageState : NavigationBarState.PROFIL, navigationIndexItem : i);
break;
}
}
Widget buildScreen(NavigationBarState page)
{
switch (page)
{
case NavigationBarState.HOME:
return HomeScreen();
break;
case NavigationBarState.PROFIL:
return Text("Page under construction");
break;
}
return null;
}
}
class NavigationBarModel {
const NavigationBarModel({this.pageState, this.navigationIndexItem});
final NavigationBarState pageState;
final int navigationIndexItem;
}
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
我的导航通知程序:
class NavigationBarScreen extends HookWidget
{
@override
Widget build(BuildContext context) {
print('build navigationScreen');
final _pageModel = useProvider(navigationProvider.state);
return SafeArea(
child: Scaffold(
body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
bottomNavigationBar: 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: _pageModel.navigationIndexItem,
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: context.read(navigationProvider).selectPage,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
),
),
);
}
}
enum NavigationBarState
{
HOME, PROFIL
}
class NavigationNotifier extends StateNotifier<NavigationBarModel>
{
NavigationNotifier() : super(_initialPage);
static const int _initialIndex = 0;
static const NavigationBarState _initialState = NavigationBarState.HOME;
static const _initialPage = NavigationBarModel(pageState : _initialState, navigationIndexItem : _initialIndex);
void selectPage(int i)
{
switch (i)
{
case 0:
state = NavigationBarModel(pageState : NavigationBarState.HOME, navigationIndexItem : i);
break;
case 1:
state = NavigationBarModel(pageState : NavigationBarState.PROFIL, navigationIndexItem : i);
break;
}
}
Widget buildScreen(NavigationBarState page)
{
switch (page)
{
case NavigationBarState.HOME:
return HomeScreen();
break;
case NavigationBarState.PROFIL:
return Text("Page under construction");
break;
}
return null;
}
}
class NavigationBarModel {
const NavigationBarModel({this.pageState, this.navigationIndexItem});
final NavigationBarState pageState;
final int navigationIndexItem;
}
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
在run inspector中,我有以下内容:
class NavigationBarScreen extends HookWidget
{
@override
Widget build(BuildContext context) {
print('build navigationScreen');
final _pageModel = useProvider(navigationProvider.state);
return SafeArea(
child: Scaffold(
body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
bottomNavigationBar: 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: _pageModel.navigationIndexItem,
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: context.read(navigationProvider).selectPage,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
),
),
);
}
}
enum NavigationBarState
{
HOME, PROFIL
}
class NavigationNotifier extends StateNotifier<NavigationBarModel>
{
NavigationNotifier() : super(_initialPage);
static const int _initialIndex = 0;
static const NavigationBarState _initialState = NavigationBarState.HOME;
static const _initialPage = NavigationBarModel(pageState : _initialState, navigationIndexItem : _initialIndex);
void selectPage(int i)
{
switch (i)
{
case 0:
state = NavigationBarModel(pageState : NavigationBarState.HOME, navigationIndexItem : i);
break;
case 1:
state = NavigationBarModel(pageState : NavigationBarState.PROFIL, navigationIndexItem : i);
break;
}
}
Widget buildScreen(NavigationBarState page)
{
switch (page)
{
case NavigationBarState.HOME:
return HomeScreen();
break;
case NavigationBarState.PROFIL:
return Text("Page under construction");
break;
}
return null;
}
}
class NavigationBarModel {
const NavigationBarModel({this.pageState, this.navigationIndexItem});
final NavigationBarState pageState;
final int navigationIndexItem;
}
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
编辑:在我的导航栏屏幕中,我更改了以下内容:
body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
据此:
body : useProvider(navigationProvider).buildScreen(_pageModel.pageState),
context.read()必须在onPressed、onTap、。。。但是我得到了相同的结果,我的navigationBarScreen被调用了两次…我无法运行您的代码,因为缺少部分,但我最好的猜测是,因为您正在查看提供程序本身和提供程序状态,所以它被调用了两次
@覆盖
小部件构建(构建上下文){
打印(“构建导航屏幕”);
//这是你正在收听的国家广播
final _pageModel=useProvider(navigationProvider.state);
返回安全区(
孩子:脚手架(
//这里您正在收听提供商的节目
正文:context.read(navigationProvider).buildScreen(_pageModel.pageState),
我建议重构StateNotifier,而不是从navigationProvider状态获取页面模型并将其传递回navigationProvider
class NavigationNotifier扩展了StateNotifier
{
NavigationNotifier():超级(\u initialPage);
静态常数int _initialIndex=0;
静态常量NavigationBarState _initialState=NavigationBarState.HOME;
静态常量_initialPage=NavigationBarModel(页面状态:_initialState,navigationIndexItem:_initialIndex);
无效选择页(int i)
{
开关(一)
{
案例0:
状态=NavigationBarModel(页面状态:NavigationBarState.HOME,navigationIndexItem:i);
打破
案例1:
状态=NavigationBarModel(页面状态:NavigationBarState.profile,navigationIndexItem:i);
打破
}
}
Widget buildScreen()
{
开关(state.pageState)
{
案例导航BarState.HOME:
返回主屏幕();
打破
案例导航BarState.profile:
返回文本(“正在构建的页面”);
打破
}
返回null;
}
}
然后从构建方法的顶部删除
final\u pageModel=useProvider(navigationProvider.state);
。感谢您的回复。