【问题标题】:Flutter Call Set State from another Class来自另一个类的 Flutter 调用集状态
【发布时间】:2020-03-12 03:50:07
【问题描述】:

所以我正在构建一个页面,其中有一些按钮,这些按钮将是动态选项。当您选择它突出显示的选项时,将小部件添加到列表中,然后我希望它在页面顶部显示列表。

我可以在调试模式下查看列表,所以我知道当按钮被按下时它被添加到列表中。

然而,没有发生的是页面状态没有刷新,用户无法看到。

如何让按钮同时设置其他小部件的状态以查看列表?

所以这是第一页。此页面具有将数据传递给标签的代码当按下标签并将项目添加到数字哈希列表中时,该列表位于第一个展开中

已添加评论

    class Digital extends StatefulWidget {
      @override
      _DigitalState createState() => _DigitalState();
    }

    class _DigitalState extends State<Digital> {
      final postRefresh = ChangeNotifier();

      bool digitalSelected = false;
      List digitalHash = new List();

      @override
      void initState() {
        super.initState();
      }

      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Color(0xff0E0E0F),
          appBar: AppBar(
            iconTheme: IconThemeData(
              color: Color(0xffff9900),
            ),
            centerTitle: true,
            backgroundColor: Colors.black,
            title: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Text(
                  "#", style: TextStyle(fontSize: 25, color: Color(0xffff9900), fontFamily: 'Dokyo'),
                ),
                Text("digital", style: TextStyle(color: Colors.white, fontFamily: 'Dokyo'),)
              ],
            ),
          ),
          body: Column(
            children: <Widget>[
              Expanded(
                flex: 3,
                child: Container(
                  child: Row(
                    children: <Widget>[
//this is where the list is being displayed
                    for (var digitalHashs in digitalHash) Text(digitalHashs, style: TextStyle(color: Colors.white, fontSize: 20),),
                    ],
                  ),
                  color: Colors.blue
                ),
              ),
              Expanded(
                flex: 6,
                child: Container(
                  color: Colors.black,
                  child: ListView(
                    padding: EdgeInsets.fromLTRB(25, 5, 25, 5),
                    children: <Widget>[
                      Tag(
                        tag: "#Digital",
                        isSelected: digitalSelected,
                        list: digitalHash,
                      ),
                    ],
                  ),
                ),
              ),

我希望能够重用标签...这里是标签元素

class Tag extends StatefulWidget {
  final String tag;
  bool isSelected;
  List list;
  Widget page;


  Tag({Key key, @required this.tag, @required this.isSelected, this.list, this.page}) : super(key: key);

  @override
  _TagState createState() => _TagState();
}

class _TagState extends State<Tag> with SingleTickerProviderStateMixin{
  AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
  }

  @override
  void dispose() {
    super.dispose();
    _animationController.dispose();
  }

  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.fromLTRB(0, 5, 0, 5),
      height: 50,
      decoration: BoxDecoration(
          color: widget.isSelected ? Color(0xffff9900) : Colors.black,
          border: Border.all(color: Colors.white),
          borderRadius: BorderRadius.circular(10)),
      child: InkWell(
        onTap: () {
          _handleOnPressed();
        },
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Container(
                padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
                alignment: Alignment.centerLeft,
                child: Text(
                  widget.tag,
                  style: TextStyle(
                      fontSize: 20, color: widget.isSelected ? Colors.black : Colors.white, fontFamily: 'Dokyo'),
                )),
            Container(
                padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
                child: AnimatedIcon(
                  icon: AnimatedIcons.home_menu,
                  progress: _animationController,
                  color: widget.isSelected ? Colors.black : Colors.white,
                ))
          ],
        ),
      ),
    );
  }

  void _handleOnPressed() {
    setState(() {
      widget.isSelected = !widget.isSelected;
      widget.isSelected
          ? _animationController.forward()
          : _animationController.reverse();
      widget.isSelected ? widget.list.add(widget.tag) : widget.list.remove(widget.tag);
      print(widget.list);
    });
  }
}

当我推送标签时,数字哈希列表没有更新,没有错误。但标签确实突出显示。

我只是想更新一个展开的部分,以便它显示列表。

【问题讨论】:

  • 你能把代码贴到那个吗?需要更多关于你在哪里使用什么等的信息。
  • 请贴出运行此程序时终端中弹出的代码和任何错误日志,以便我们提供更好的帮助。
  • OK 代码更新

标签: flutter dart


【解决方案1】:

您可以在下面复制粘贴运行完整代码
我还提供了工作演示
在 DigitalStage 中添加两个函数用于添加/删除列表
使用final key = new GlobalKey&lt;DigitalState&gt;();你可以从Tag中调用这两个函数

代码sn-p

final key = new GlobalKey<DigitalState>();

class Digital extends StatefulWidget {
  Digital({ Key key }) : super(key: key);
...
    void add(String tag) {
    setState(() {
      digitalHash.add(tag);
    });

  }

  void remove(String tag) {
    setState(() {
      digitalHash.remove(tag);
    });

  }
...
widget.isSelected
          ?  key.currentState.add(widget.tag)
          : key.currentState.remove(widget.tag);

工作演示

完整代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: Digital(key: key),
    );
  }
}


final key = new GlobalKey<DigitalState>();

class Digital extends StatefulWidget {
  Digital({ Key key }) : super(key: key);

  @override
  DigitalState createState() => DigitalState();
}

class DigitalState extends State<Digital> {
  final postRefresh = ChangeNotifier();

  bool digitalSelected = false;
  List digitalHash = new List();

  void add(String tag) {
    setState(() {
      digitalHash.add(tag);
    });

  }

  void remove(String tag) {
    setState(() {
      digitalHash.remove(tag);
    });

  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        //key: key,
        backgroundColor: Color(0xff0E0E0F),
        appBar: AppBar(
          iconTheme: IconThemeData(
            color: Color(0xffff9900),
          ),
          centerTitle: true,
          backgroundColor: Colors.black,
          title: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Text(
                "#",
                style: TextStyle(
                    fontSize: 25,
                    color: Color(0xffff9900),
                    fontFamily: 'Dokyo'),
              ),
              Text(
                "digital",
                style: TextStyle(color: Colors.white, fontFamily: 'Dokyo'),
              )
            ],
          ),
        ),
        body: Column(children: <Widget>[
          Expanded(
            flex: 3,
            child: Container(
                child: Row(
                  children: <Widget>[
//this is where the list is being displayed
                    for (var digitalHashs in digitalHash)
                      Text(
                        digitalHashs,
                        style: TextStyle(color: Colors.white, fontSize: 20),
                      ),
                  ],
                ),
                color: Colors.blue),
          ),
          Expanded(
            flex: 6,
            child: Container(
              color: Colors.black,
              child: ListView(
                padding: EdgeInsets.fromLTRB(25, 5, 25, 5),
                children: <Widget>[
                  Tag(
                    tag: "#Digital",
                    isSelected: digitalSelected,
                    list: digitalHash,
                  ),
                ],
              ),
            ),
          )
        ]));
  }
}

class Tag extends StatefulWidget {
  final String tag;
  bool isSelected;
  List list;
  Widget page;

  Tag(
      {Key key,
      @required this.tag,
      @required this.isSelected,
      this.list,
      this.page})
      : super(key: key);

  @override
  _TagState createState() => _TagState();
}

class _TagState extends State<Tag> with SingleTickerProviderStateMixin {
  AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
  }

  @override
  void dispose() {
    super.dispose();
    _animationController.dispose();
  }

  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.fromLTRB(0, 5, 0, 5),
      height: 50,
      decoration: BoxDecoration(
          color: widget.isSelected ? Color(0xffff9900) : Colors.black,
          border: Border.all(color: Colors.white),
          borderRadius: BorderRadius.circular(10)),
      child: InkWell(
        onTap: () {
          _handleOnPressed();
        },
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Container(
                padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
                alignment: Alignment.centerLeft,
                child: Text(
                  widget.tag,
                  style: TextStyle(
                      fontSize: 20,
                      color: widget.isSelected ? Colors.black : Colors.white,
                      fontFamily: 'Dokyo'),
                )),
            Container(
                padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
                child: AnimatedIcon(
                  icon: AnimatedIcons.home_menu,
                  progress: _animationController,
                  color: widget.isSelected ? Colors.black : Colors.white,
                ))
          ],
        ),
      ),
    );
  }

  void _handleOnPressed() {
    setState(() {
      widget.isSelected = !widget.isSelected;
      widget.isSelected
          ? _animationController.forward()
          : _animationController.reverse();
      widget.isSelected
          ?  key.currentState.add(widget.tag)
          : key.currentState.remove(widget.tag);
      print(widget.list);
    });
  }
}

【讨论】:

  • 谢谢!单击按钮时出现错误。颤振:处理手势时抛出以下 NoSuchMethodError:颤振:方法“添加”在 null 上被调用。
  • 所以我回去尝试玩这个。该列表没有添加任何内容。我试图使 Tag 类可重用,因为我最终将有许多不同类型的标签添加到列表中。因此,根据我从错误中收集到的信息,我实际上并没有在列表中添加任何内容。
  • 另外,我将您的代码复制并粘贴到一个新项目中,它可以工作,删除不起作用,它只是添加它,第二次单击应该删除它。但这意味着我构建它的方式有些东西。所以我要看看那个。你知道为什么删除不起作用吗? isSelected 并没有从我可以看到的真/假形式改变。
  • 我有真/假工作,我仍然收到错误...所以这是我缺少的东西,但是当我将它复制到一个新项目中时,它工作正常随心所欲。
  • 好的,我找到了问题。所以它是全局键,所以让我解释一下,有一个使用构造函数构建子页面的主页面,其中创建了 Digital。最终会有大量类别,我想重用它.. 所以全局键被多个小部件使用。因此,例如主页 -> 类别 -> 子类别 -> 数字 -> 标签,但它也可以是主页 -> 类别 -> 子类别 -> 艺术 -> 标签
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 2022-12-18
  • 2020-05-18
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多