Flutter 使用RiverPod状态管理改变抽屉状态

Flutter 使用RiverPod状态管理改变抽屉状态,flutter,flutter-provider,riverpod,Flutter,Flutter Provider,Riverpod,通过使用RiverPod状态管理,我试图通过自我完善来学习如何使用它,我做了一个简单的项目,我试图通过按下另一个类和文件上的AppBar中的图标来打开Drawer,不幸的是,像使用RiverPod示例代码一样,我的代码不能正常工作,单击图标时不会触发主类 我只想通过单击AppBar上的图标打开抽屉 主文件: void main(){ runApp(ProviderScope(子级:MyApp()); } 类MyApp扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返回材料PP( 标题:

通过使用
RiverPod
状态管理,我试图通过自我完善来学习如何使用它,我做了一个简单的项目,我试图通过按下另一个类和文件上的
AppBar
中的图标来打开
Drawer
,不幸的是,像使用
RiverPod
示例代码一样,我的代码不能正常工作,单击图标时不会触发主类

我只想通过单击AppBar上的图标打开抽屉

主文件:

void main(){
runApp(ProviderScope(子级:MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“Riverpod演示”,
主题:主题数据(
主样本:颜色。蓝色,
视觉密度:视觉密度。自适应平台密度,
),
主页:MyHomePage(),
);
}
}
类MyHomePage扩展StatefulWidget{
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
GlobalKey _scaffoldKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
最终抽屉状态=StateNotifierProvider(()=>抽屉可视性();
退货消费者(
构建器:(上下文,读取,ux){
最终状态=读取(抽屉状态);
打印('CLICKED$state');
如果(州){
_scaffoldKey.currentState.openDrawer();
}
返回脚手架(
钥匙:_scaffoldKey,
appBar:MyAppBar(),
抽屉:抽屉(),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
正文(
“您已经按了这么多次按钮:”,
),
],
),
),
);
},
);
}
}
AppBar
类文件内容:

类MyAppBar使用PreferredSizeWidget扩展无状态小部件{
@凌驾
小部件构建(构建上下文){
最终抽屉状态=StateNotifierProvider(()=>抽屉可视性();
返回AppBar(
自动嵌入:false,
标题:世界其他地区(
mainAxisAlignment:mainAxisAlignment.start,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
图标按钮(图标:图标(Icons.menu),ON按下:(){
read(抽屉状态).changeDrawersState();
}),
文本(“我的样本”),
],
),
);
}
@凌驾
Size get preferredSize=>Size.fromHeight(kToolbarHeight);
}
最后,
RiverPod
class

类抽屉可视性扩展StateNotifier{
抽屉可视性():超级(假);
void changeDrawerState()=>state=true;
}
另一个问题是,当我第一次获得此输出时启动应用程序:

I/flutter (12240): CLICKED false
I/flutter (12240): CLICKED false

如果不点击图标,而不是消费者,你应该尝试使用
ProviderListener
,当你想显示对话框、快捷键、按下/弹出,或者在这种情况下打开抽屉时,效果会更好。最后,不要在每个构建方法中创建最终的提供者,只需创建一次作为最终的全局参数,以便在每个小部件中读取/查看它时使用相同的实例

/// Create a final global StateNotifierProvider in your file instead of one inside each widget
final drawerState = StateNotifierProvider<DrawerVisibility>((_)=>DrawerVisibility());

class _MyHomePageState extends State<MyHomePage> {
  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return ProviderListener<bool>(
      onChange: (context, state) {
        if(state) _scaffoldKey.currentState.openDrawer();
        //maybe check if the _scaffoldKey is mounted or is the drawer open before doing something
      },
      provider: drawerState.state,
      child: Scaffold(
        key: _scaffoldKey,
        appBar: MyAppBar(),
        drawer: Drawer(),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
            ],
          ),
        ),
      ),
    );
  }
}
///在文件中创建最终的全局StateNotifierProvider,而不是在每个小部件中创建一个
最终抽屉状态=StateNotifierProvider(()=>抽屉可视性();
类_MyHomePageState扩展状态{
GlobalKey _scaffoldKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回ProviderListener(
onChange:(上下文、状态){
if(state)_scaffoldKey.currentState.openDrawer();
//在做某事之前,也许要检查一下脚手架钥匙是否已安装或抽屉是否打开
},
提供程序:drawerState.state,
孩子:脚手架(
钥匙:_scaffoldKey,
appBar:MyAppBar(),
抽屉:抽屉(),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
正文(
“您已经按了这么多次按钮:”,
),
],
),
),
),
);
}
}
MyAppBar
中删除抽屉状态,使其使用与
主页
相同的全局设置,并且在某个时候关闭抽屉时,应再次将状态设置为false