【问题标题】:Flutter change Drawer state using RiverPod State managementFlutter 使用 RiverPod 状态管理改变 Drawer 状态
【发布时间】:2021-02-10 11:10:19
【问题描述】:

通过使用RiverPod 状态管理,我尝试通过自我提升来学习以及如何使用我制作了一个简单的项目,我试图通过按下AppBar 中的图标打开Drawer这是在另一个类和文件上,不幸的是,与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

无需点击任何图标

【问题讨论】:

    标签: flutter flutter-provider riverpod


    【解决方案1】:

    您应该尝试使用ProviderListener,而不是Consumer,当您想要显示对话框、小吃栏、推/弹出,或者在这种情况下打开抽屉时,它会更好。最后,无需在每个构建方法中创建最终提供程序,只需将其创建一次作为最终全局参数,因此在您读取/观看的每个小部件中,它使用相同的实例

    /// 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 中删除drawerState,因此它使用与HomePage 相同的全局变量,在某个时候关闭抽屉时,您应该再次将状态设为false

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 2022-09-24
      • 2021-08-20
      • 2021-04-11
      相关资源
      最近更新 更多