代码之家  ›  专栏  ›  技术社区  ›  Blasanka

是否可以使用小部件树中其他位置的按钮更改其他类的状态?

  •  0
  • Blasanka  · 技术社区  · 6 年前

    这是我的小工具树。我想更改 MemberSection 当我按下时上课 RaisedButton AdminSection 班级。 两个 成员节 行政部门 HomePage 班级。

    enter image description here

    以下是DART文件:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        MaterialApp(
          home: HomePage(),
        ),
      );
    }
    
    class HomePage extends StatelessWidget {
      final int count = 0;
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[MemberSection(count), AdminSection(count)],
          ),
        );
      }
    }
    
    class MemberSection extends StatefulWidget {
      MemberSection(this.count);
    
      final int count;
    
      @override
      _MemberSectionState createState() => new _MemberSectionState();
    }
    
    class _MemberSectionState extends State<MemberSection> {
      @override
      Widget build(BuildContext context) {
        return new Text('${widget.count} member(s)');//I need to change this widget
      }
    }
    
    class AdminSection extends StatefulWidget {
      AdminSection(this.count);
    
      final int count;
    
      @override
      _AdminSectionState createState() => new _AdminSectionState();
    }
    
    class _AdminSectionState extends State<AdminSection> {
      void incrementer() {
        setState(() {
          //widget.count++; //cannt do
        });
      }
    
      void decrementer() {
        setState(() {
          //widget.count--; //cannt do
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Column(
          children: <Widget>[
            Text('${widget.count} admin(s)'),//Also, I need to change this widget
            ButtonBar(
              children: <Widget>[
                RaisedButton(
                  child: Text('add a member'),
                  onPressed: incrementer,
                ),
                RaisedButton(
                  child: Text('delete a member'),
                  onPressed: decrementer,
                ),
              ],
            ),
          ],
        );
      }
    }
    

    注意:此示例用于演示我的问题。

    我知道我可以实现 incrementer decrementer 在里面 主页 类并将函数传递给小部件,但是根据这个场景,它无法完成,因为 上升按钮 小部件位于小部件树的另一侧。

    更新:

    链接的重复问题与我的问题不同,因为我没有实例化 成员节 里面 行政部门

    1 回复  |  直到 6 年前
        1
  •  1
  •   Blasanka    6 年前

    是的,这是可能的。

    最简单的方法是使用 InheritedWidget

    你可能记得一个方法 of(context) ,例如:

    MediaQuery.of(context).size
    Navigator.of(context).pop()
    Theme.of(context).canvasColor
    

    这些是继承的小部件。您正在使用 of() 应用程序中的任何地方都可以访问主题,因为它们是继承的。使用 of 方法可以在实现小部件树之后更改小部件树的状态。

    因此,您的示例代码应该如下所示:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        MaterialApp(
          home: MyApp(),
        ),
      );
    }
    
    //this is a newly added stateful widget to use inherited widget
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      int count = 0;
    
      void incrementer() {
        setState(() {
          count++;
        });
      }
    
      void decrementer() {
        setState(() {
          count--;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return CounterState(
          count: count,
          incrementer: incrementer,
          decrementer: decrementer,
          child: HomePage(),
        );
      }
    }
    
    //this is the inherited widget
    class CounterState extends InheritedWidget {
      CounterState({Key key, this.count, this.incrementer, this.decrementer, Widget child})
          : super(key: key, child: child);
    
      final int count;
      final Function incrementer;
      final Function decrementer;
    
      @override
      bool updateShouldNotify(CounterState oldWidget) {
        return count != oldWidget.count;
      }
    
      static of(BuildContext context) {
        return context.inheritFromWidgetOfExactType(CounterState);
      }
    }
    
    //make below classes stateless(not must but useless)
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              MemberSection(),
              AdminSection()
            ],
          ),
        );
      }
    }
    
    class MemberSection extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final counterState = CounterState.of(context);
        return new Text('${counterState.count} member(s)');
      }
    }
    
    class AdminSection extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final counterState = CounterState.of(context);
        return new Column(
          children: <Widget>[
            Text('${counterState.count} admin(s)'),
            ButtonBar(
              children: <Widget>[
                RaisedButton(child: Text('add a member'), onPressed: counterState.incrementer,),
                RaisedButton(child: Text('delete a member'), onPressed: counterState.decrementer,),
              ],
            ),
          ],
        );
      }
    }
    

    可以找到一个很好的教程 here .