首页 > 解决方案 > Dart 变量不是最终警告

问题描述

所以我在下面编写了这段代码来制作一个Icon Stateful内部Stateless小部件。

class IconState extends StatefulWidget {
  final bool isSelected;

  IconState({
    this.isSelected,
  });

  _IconState state; // this is not final because I need to assign it below

  void toggle() {
    state.change();
  }

  @override
  _IconState createState() => state = new _IconState(
        isSelected: this.isSelected,
      );
}

class _IconState extends State<IconState> {
  _IconState({
    this.isSelected,
  });

  bool isSelected = false;

  Widget _unSelected = Icon(
    null,
  );

  Widget _selected = Icon(
    Icons.check_outlined,
    color: Colors.red,
  );

  void change() {
    setState(() {
      this.isSelected = this.isSelected == true ? false : true;
    });
  }

  Icon evaluate() {
    if (isSelected) {
      return _selected;
    }
    return _unSelected;
  }

  @override
  Widget build(BuildContext context) {
    return evaluate();
  }
}

为了更新图标的状态,我toggle()从我的无状态小部件中调用该方法。

Dart 在 @immutable 类中给了我一个非最终实例警告,但我找不到解决方法。

我试过以下:

final _IconState state = new _IconState(
    isSelected: this.isSelected, // throws an error => Invalid reference to 'this' expression.
  );

也是这个,但也不起作用

final _IconState state;

IconState({this.isSelected}) {
  this.state = new _IconState(
    isSelected: this.isSelected,
  );
};

有解决方法吗?

标签: flutterdart

解决方案


我会将 isSelected 布尔值放在外部状态管理类中,然后您可以返回 2 个单独的小部件以响应更改。否则,您将不得不更改将显示图标的小部件内部的状态。像这样的东西:

class IconState extends ChangeNotifier{
  bool _isSelected;
  //any other needed state

  bool get isSelected => _isSelected;

  void changeIsSelected(bool selected) {
    _isSelected = selected;
    notifyListeners();
  }
 }

然后使用 ChangeNotifierProvider 注入状态并调用 change 方法。

final iconStateProvider = ChangeNotifierProvider((ref) => IconState());

现在,您可以使用 iconStateProvider 来访问状态和方法。您将需要一个 Builder 或 Consumer 小部件来监听状态的变化。

  Consumer( builder: (context, watch, child) {
    final iconState = watch(iconStateProvider);
    if (iconState.isSelected) {
      return Icon();
    } else {
      return null;
    }

这是使用 Riverpod 库,它只是众多外部状态管理库中的一个。我建议在 YouTube 上观看不同库的教程,然后选择最适合您的。


推荐阅读