0

让我们假设一个类“SpecialButton”及其状态类“SpecialButtonState”

class SpecialButton extends StatefulWidget {
  bool active = false;
  SpecialButton({Key key}) : super(key: key);
  @override
  SpecialButtonState createState() => SpecialButtonState();
}

class SpecialButtonState extends State<SpecialButton> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        decoration:
            BoxDecoration(color: this.widget.active ? COLOR_1 : COLOR_2),
        child: null);
  }
}

在父小部件中,我管理其中的几个按钮。因此,我想为他们分配一个状态。我尝试的解决方案是在 SpecialButton 类中引入一个“活动”标志,我可以轻松地从父小部件将其设置为 true 或 false。然后我可以在状态类的构建函数中使用它来为按钮着色。不幸的是,这并不能完全起作用,因为它不会立即更新按钮(它需要某种状态更新,例如通过将鼠标悬停在元素上)。

我的第二个想法是将这个标志作为 SpecialButtonState 类的属性状态引入

class SpecialButton extends StatefulWidget {
  SpecialButton({Key key}) : super(key: key);
  @override
  SpecialButtonState createState() => SpecialButtonState();
}

class SpecialButtonState extends State<SpecialButton> {
  bool active;

  @override
  void initState() {
    super.initState();
    this.active = false;
  }

  activate() {
    this.setState(() {
      active = true;
    });
  }

  deactivate() {
    this.setState(() {
      active = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        decoration: BoxDecoration(color: this.active ? COLOR_1 : COLOR_2),
        child: null);
  }
}

据我了解,这将是使用颤振的正确方法,但似乎我无法从 SpecialButton 类或包含小部件的父类访问“激活”或“停用”功能。

所以我的问题是:我如何(直接或间接通过函数)从相应的 StatefulWidget 类或包含它的父 Widget 修改状态?

在 Stack Overflow 上已经有一些类似的问题,我可以在其中找到使用或不使用全局键的提示,我发现这种行为具有误导性。此外,由于颤振的快速持续发展,它们可能已经过时,所以我再次就这个确切的用例提出这个(类似的)问题。

编辑:我忘了提到在创建后更改此标志至关重要,因此它将在其生存期间多次更改。这需要小部件重绘。

4

2 回答 2

1

如果您是这样,则不必使用有状态小部件SpecialButton。您可以active使用无状态小部件和键处理标志。示例代码:


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

  @override
  State<SomeParent> createState() => SomeParentState();
}

class SomeParentState extends State<SomeParent> {
  bool _button1IsActive = false;
  bool _button2IsActive = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          SpecialButton(
            key: UniqueKey(),
            active: _button1IsActive,
          ),
          SizedBox(height: 8),
          SpecialButton(
            key: UniqueKey(),
            active: _button2IsActive,
          ),
          SizedBox(height: 16),
          TextButton(
            child: Text('Toggle button 1'),
            onPressed: () {
              setState(() {
                _button1IsActive = !_button1IsActive;
              });
            },
          ),
          SizedBox(height: 8),
          TextButton(
            child: Text('Toggle button 2'),
            onPressed: () {
              setState(() {
                _button2IsActive = !_button2IsActive;
              });
            },
          ),
        ],
      ),
    );
  }
}

class SpecialButton extends StatelessWidget {
  final bool active;

  const SpecialButton({Key key, this.active = false}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 40,
      width: 40,
      decoration: BoxDecoration(color: active ? Colors.red : Colors.blue),
    );
  }
}

SomeParent是我的幻想,例如。不知道你的父母是什么。键在这里很重要。SpecialButton当应该重建具有相同类型(例如)的特定小部件时,它们会告诉小部件树。

请尝试这种方法,它应该工作。

于 2021-02-26T07:58:10.383 回答
1

正如 nvoigt 所说,您的按钮甚至可以是无状态小部件,但它们的父级应该是有状态的,您应该为它们提供相应的值。例如:

import 'package:flutter/material.dart';

class Parent extends StatefulWidget {
  @override
  _ParentState createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  bool isEnabled = false;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        StateLessButton1(isEnabled: isEnabled),
        StateLessButton1(isEnabled: !isEnabled),
        FloatingActionButton(onPressed: (){
          setState(() {
                      isEnabled = !isEnabled;
                    });
        })
      ],
      
    );
  }
}

现在它只取决于您何时想要更改该值。如果你想在你的按钮内改变它,我建议你使用一个带有 ChangeNotifier 的类和一个改变值的函数。否则我建议不要将你的树分成多个文件

于 2021-02-26T08:03:38.540 回答