使用RiverPod状态管理的颤振变化抽屉状态

问题描述

通过使用RiverPod状态管理,我尝试进行自我改进,以学习和使用该状态我做了一个简单的项目,并且试图通过按图标打开DrawerAppBar(位于另一个类和文件中)中,不幸的是,与RiverPod示例代码一样,我的代码无法正常工作,并且主类也不会在单击图标时触发

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

主文件:

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Riverpod Demo',theme: ThemeData(
        primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

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

  @override
  Widget build(BuildContext context) {
    final drawerState = StateNotifierProvider<DrawerVisibility>((_)=>DrawerVisibility());
    return Consumer(
      builder: (context,read,_) {
        final state = read(drawerState.state);
        print('CLICKED $state');
        if(state){
          _scaffoldKey.currentState.openDrawer();
        }
        return 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:',],);
      },);
  }
}

AppBar类文件内容:

class MyAppBar extends StatelessWidget with PreferredSizeWidget {
  @override
  Widget build(BuildContext context) {
    final drawerState = StateNotifierProvider<DrawerVisibility>((_)=>DrawerVisibility());
    return AppBar(
      automaticallyImplyLeading: false,title: Row(
        mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[
          IconButton(icon: Icon(Icons.menu),onPressed: () {
            context.read(drawerState).changeDrawerState();
          }),Text('My Sample'),);
  }

  @override
  Size get preferredSize => Size.fromHeight(kToolbarHeight);
}

最后是RiverPod

class DrawerVisibility extends StateNotifier {
  DrawerVisibility() : super(false);

  void changeDrawerState() => state = true;
}

另一个问题是我第一次启动应用程序时得到以下输出:

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

无需单击任何图标

解决方法

您应该尝试使用Consumer而不是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:',),],);
  }
}

然后在MyAppBar中删除抽屉状态,以便它使用与HomePage相同的全局变量,并且在关闭抽屉时,还应再次将状态设置为false

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...