在Flutter中设置父小部件的状态

时间:2019-11-18 18:47:10

标签: flutter dart

我不确定我是否正确构建了代码,但是我试图节省我的第一个应用程序项目的时间。

我有一个页面,我将在其中生成几个选择按钮,当您按下该按钮时,我希望将文本添加到列表中。我选择不构建传统按钮,而是选择另一个可以控制状态的小部件。

我遇到的问题是这个选择器按钮似乎工作正常。它进行了更改并验证是否已将其添加到列表中,我将其打印到控制台上并可以看到它。

问题是我选择按钮时显示容器没有更新。

我尝试了全局密钥,但是问题在于,由于生成了按钮,因此它们共享一个全局密钥。 1个按钮似乎很好,我可以传递密钥,但是我对所有这些知识的了解也很有限,所以我可能做错了什么。

我当前的代码路径如下。 主页->类别->子类别->页面(在这种情况下为数字)->标签(按钮)。

import 'package:flutter/material.dart';
import 'package:onlytagsprod/widgets/tag.dart';

final digital = 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();
  String displays;

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


  callback() {
    setState(() {
    });
  }


  @override
  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>[
//Display the List here*********************************************
                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,
                  ),
                  Tag(
                    tag: "#DigitalLife",
                    isSelected: digitalSelected,
                    list: digitalHash,
                  ),
                ],
              ),
            ),
          )
        ]));
  }
}

此显示页面我希望能够添加任意数量的标签选项。

这是标签页。

import 'package:flutter/material.dart';
import 'package:onlytagsprod/subpages/digital.dart';

class Tag extends StatefulWidget {
  final String tag;
  bool isSelected;
  List list;
  Function(List) callback;

  Tag(
      {Key key,
        @required this.tag,
        @required this.isSelected,
        this.list,
      this.callback})
      : 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);
    });
  }
}

由于我已经尽一切方式尝试知道如何解决状态更改了,所以代码变得有点草率了。所以我知道了不需要的东西。

我才刚刚起步

1 个答案:

答案 0 :(得分:1)

将状态更改更改为父项或祖先的最简单方法是通过回调方法。话虽如此,您已经在callback类中定义了Tag字段,但是父窗口小部件中的build方法和_TagState类都没有引用它。

您需要做的就是更改_handleOnPressed方法以执行回调:

void _handleOnPressed() {
  ...
  widget.callback?.call(widget.list);
}

并在父窗口小部件中更改Tag的构造函数以分配它们:

Tag(
  tag: "#DigitalLife",
  isSelected: digitalSelected,
  list: digitalHash,
  callback: (list) => setState(() => digitalHash = list),
),