【问题标题】:How can I Insert another Widget in place of another when one is pressed?当一个小部件被按下时,如何插入另一个小部件来代替另一个?
【发布时间】:2020-12-14 03:38:12
【问题描述】:

我是一个入门级的 Flutter 开发者,我在这个问题上被困了一段时间,我尝试了不同的方法

我正在尝试制作“注释标题”(那个特定的小部件),弹出

The app_issue description

那么这应该显示 desired result

“我的笔记”选项卡下的两个不同内容是两个有状态的小部件,而“我的笔记”选项卡本身就是另一个有状态的小部件

我尝试过使用一个函数,但它不起作用

enum MyNoteContent {
  staticNote,
  dynamicNote,
}

MyNoteContent selectedContent = MyNoteContent.staticNote;

Widget updateMyNotes() {
  if (selectedContent == MyNoteContent.staticNote) {
    return MyNoteStatic();
  } else {
    return MyNoteDynamic();
  }
}

然后我调用 MyNotes Widget 中的函数

class _MyNotesTabState extends State<MyNotesTab> {
  @override
  Widget build(BuildContext context) {
    return updateMyNotes();
  }
}

我试图更新显示的第一个内容中的值(在它自己的小部件中),以便当它被按下时,它应该改变

class _MyNoteStaticState extends State<MyNoteStatic> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: RawMaterialButton(
          onPressed: () {
            setState(() {
              selectedContent = MyNoteContent.dynamicNote;
              updateMyNotes();
            });
          },

但它不起作用

Code to Reproduce the Problem

【问题讨论】:

  • 请创建一个minimal reproducible example。有点不清楚您现在实际拥有的代码是什么。制作一些我们可以粘贴到 Dartpad 中并显示问题的东西。
  • 我刚刚添加了它。这是 GitHubGist 的链接。
  • 将完整示例直接粘贴到您的问题中,并尝试删除尽可能多的无关代码。
  • setState 不会影响其他小部件!
  • @Yadu 这不是很准确。在子进程中调用setState 不能直接影响父进程,但反转它会产生影响。

标签: flutter dart


【解决方案1】:

这里的问题是您调用的setState 是针对_MyNoteStaticState 类的。这意味着它只会重建MyNoteStatic 小部件。但是为了改变页面,你需要重建它的父 _MyNotesTabState。所以你需要调用_MyNotesTabStatesetState 方法,这可以通过将回调从_MyNotesTabState 传递到_MyNoteStaticState 来完成。

首先,将updateMyNotesselectedContent 移入_MyNotesTabState 类,因为这是唯一需要它们的地方。

创建一个新函数来重建_MyNotesTabState 并在_MyNotesTabState 中更改selectedContent

void changeNote() {
  setState(() {
    selectedContent = MyNoteContent.dynamicNote;
  });
}

将其传递给MyNoteStatic

Widget updateMyNotes() {
  if (selectedContent == MyNoteContent.staticNote) {
    return MyNoteStatic(changeNote);
  } else {
    return MyNoteDynamic();
  }
}

并修改MyNoteStatic 以接受此回调作为参数

class MyNoteStatic extends StatefulWidget {
  final VoidCallback callback;
  MyNoteStatic(this.callback);

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

然后将此回调传递给您的按钮,而不是您当前拥有的:

child: RawMaterialButton(
  onPressed: widget.callback,
)

包含上述更改的完整相关代码:

enum MyNoteContent {
  staticNote,
  dynamicNote,
}

class MyNotesTab extends StatefulWidget {
  @override
  _MyNotesTabState createState() => _MyNotesTabState();
}

class _MyNotesTabState extends State<MyNotesTab> {
  MyNoteContent selectedContent = MyNoteContent.staticNote;
  
  @override
  Widget build(BuildContext context) {
    return updateMyNotes();
  }
  
  Widget updateMyNotes() {
    if (selectedContent == MyNoteContent.staticNote) {
      return MyNoteStatic(changeNote);
    } else {
      return MyNoteDynamic();
    }
  }
  
  void changeNote() {
    setState(() {
      selectedContent = MyNoteContent.dynamicNote;
    });
  }
}

//Static Note
class MyNoteStatic extends StatefulWidget {
  final VoidCallback callback;
  MyNoteStatic(this.callback);

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

class _MyNoteStaticState extends State<MyNoteStatic> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: RawMaterialButton(
          onPressed: widget.callback,
...

【讨论】:

  • @davidn 另外,请尝试将您的代码直接编辑到您的问题中,以便更好地造福未来的用户。
猜你喜欢
  • 2018-03-08
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 2019-12-23
相关资源
最近更新 更多