繁体   English   中英

从appbar.actions中触发StatefulWidget更改

[英]Triggering StatefulWidget changes from appbar.actions

我在理解如何从动态AppBar操作按钮更新小部件时遇到问题。 这是我改变的扑动'新应用'来说明问题。 在我的生产应用程序中,我需要显示某些操作按钮,具体取决于当前在抽屉支架体中显示的页面小部件。

class ActionWidget extends StatefulWidget {
  final action = IconButton(
    icon: Icon(Icons.add),
    onPressed: () {
      //state.action();
    },
  );

  @override
  State<StatefulWidget> createState() {
    return ActionWidgetState();
  }
}

class ActionWidgetState extends State<ActionWidget> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'You have pushed the button this many times:',
          ),
          Text(
            '$_counter',
            style: Theme.of(context).textTheme.display1,
          ),
        ],
      ),
    );
  }

  void action() {
    setState(() {
      _counter++;
    });
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    final actionWidget = ActionWidget();
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          actionWidget.action,
        ],
      ),
      body: actionWidget,
    );
  }
}

如何触发onPressed操作时如何更新窗口小部件状态? 我目前的解决方法是这个(显然不是最优的)

class MeasurePage extends PageWidget {
  MeasurePageState state;

  @override
  State createState() => state = MeasurePageState();
...
    onPressed: () {
      state.search(context);
    },

编辑。 另一个带抽屉菜单的样本可以更好地说明问题

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  final actionWidgets = List<ActionWidget>.from([ActionWidget(1), ActionWidget(2)]);
  var selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: actionWidgets[selectedIndex],
      appBar: AppBar(
        actions: <Widget>[actionWidgets[selectedIndex].getAction()],
      ),
      drawer: Drawer(
        child: Column(
          children: <Widget>[
            Container(
              height: 33,
            ),
            FlatButton(
              child: Text('instance 1'),
              onPressed: () {
                Navigator.of(context).pop(); // close the drawer
                this.setState(() {
                  selectedIndex = 0;
                });
              },
            ),
            FlatButton(
              child: Text('instance 2'),
              onPressed: () {
                Navigator.of(context).pop(); // close the drawer
                this.setState(() {
                  selectedIndex = 1;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

class ActionWidget extends StatefulWidget {
  final actionWidgetState;
  final index;
  ActionWidget(this.index)
      : this.actionWidgetState = ActionWidgetState(index),
        super(key: GlobalKey());

  Widget getAction() {
    return IconButton(
      icon: Icon(Icons.add),
      onPressed: () {
        actionWidgetState.actionCallback();
      },
    );
  }

  @override
  State<StatefulWidget> createState() => actionWidgetState;
}

class ActionWidgetState extends State<ActionWidget> {
  int _counter = 0;
  VoidCallback actionCallback;
  final index;

  ActionWidgetState(this.index);

  @override
  Widget build(BuildContext context) {
    actionCallback = () => action();
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'Page ${widget.index}',
          ),
          Text(
            'State $index',
          ),
          Text(
            'You have pushed the button this many times:',
          ),
          Text(
            '$_counter',
            style: Theme.of(context).textTheme.display1,
          ),
        ],
      ),
    );
  }

  void action() {
    setState(() {
      _counter++;
    });
  }
}

您没有正确使用StatefulWidget。 您在StatefulWidget中调用的操作按钮应该只是按钮本身,然后您可以将要在状态中更改的数据传递给statefulWidget类。 然后在你的State类中,你可以覆盖其中的didUpdateWidget和setState。 也许可以通过这个: https//flutter.dev/docs/development/data-and-backend/state-mgmt/intro

输出:

在此输入图像描述

ActionWidget更改为此。

class ActionWidget extends StatefulWidget {
  static final ActionWidgetState actionWidgetState = ActionWidgetState();
  final action = IconButton(
    icon: Icon(Icons.add),
    onPressed: () {
      actionWidgetState.action();
    },
  );

  @override
  State<StatefulWidget> createState() {
    return actionWidgetState;
  }
} 

完整代码:

void main() => runApp(MaterialApp(home: MyHomePage()));

class ActionWidget extends StatefulWidget {
  static final ActionWidgetState actionWidgetState = ActionWidgetState();
  final action = IconButton(
    icon: Icon(Icons.add),
    onPressed: () => actionWidgetState.action(),
  );

  @override
  State<StatefulWidget> createState() => actionWidgetState;
}

class ActionWidgetState extends State<ActionWidget> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('You have pushed the button this many times:'),
          Text('$_counter', style: Theme.of(context).textTheme.display1),
        ],
      ),
    );
  }

  void action() => setState(() => _counter++);
}

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    final actionWidget = ActionWidget();
    return Scaffold(
      appBar: AppBar(actions: <Widget>[actionWidget.action]),
      body: actionWidget,
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM