繁体   English   中英

在 Flutter 中设置 Parent Widget 的 State

[英]Set State of Parent Widget in Flutter

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

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

我遇到的问题是,这个选择器按钮似乎工作正常。 它发生变化并验证它是否被添加到列表中,我将它打印到控制台并可以看到它。

问题是当我按下 select 按钮时,我的显示容器没有更新。

我尝试了一个全局键,但问题是由于按钮正在生成,它们共享一个全局键。 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);
    });
  }
}

代码变得有点草率,因为我已经尝试了所有我知道如何解决 state 更改的方法......所以我知道不需要的东西。

我只是在我的新手智慧结束

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

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

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

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

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

暂无
暂无

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

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