Класс, помеченный как @immutable, поле экземпляра не является окончательным с использованием StatefulWidget

У меня есть виджет без сохранения состояния под названием ToggleButtonsList, и одно из полей моего экземпляра isSelectedType не установлено как final. Это предупреждение, которое я получаю из-за этого:

Этот класс (или класс, от которого наследуется этот класс) помечен как '@immutable', но одно или несколько его полей экземпляра не являются окончательными: ToggleButtonsList.isSelectedType

Вот часть моего кода:

class ToggleButtonsList extends StatefulWidget {
  ToggleButtonsList({this.type, this.stringList});

  final String type;
  final List<String> stringList;
  List<bool> isSelectedType = [];

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

class _ToggleButtonsListState extends State<ToggleButtonsList> {
  @override
  Widget build(BuildContext context) {
   
   
  }
}

Мой вопрос: я подумал, что поля экземпляра должны быть установлены на final только для виджетов без сохранения состояния, а НЕ для виджетов с отслеживанием состояния. Это правда? Это предупреждение, о котором мне следует беспокоиться, поскольку я не использую StatelessWidget, или я могу его игнорировать? Когда я игнорирую предупреждение, мое приложение работает отлично.

Чтение или класса, который этот класс наследует от части предупреждения заставило меня попытаться найти в моем проекте любые StatelessWidgets, от которых этот класс может унаследовать, и единственный StatelessWidget, который у меня есть в моем проекте, - это мой main.dart :

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
          primaryColor: Colors.blueGrey,
          scaffoldBackgroundColor: Colors.blueGrey),
      home: PriceScreen(),
    );
  }
}

Изменение моего класса MyApp на StatefulWidget не избавило от предупреждения.


person London Tran    schedule 05.10.2020    source источник


Ответы (2)


Думаю ваше смешивание State и StatefulWidget класса. Сам класс Widget - это immutable, и оба StatelessWidget и StatefulWidget являются наследниками Widgetclass.

В вашем конкретном случае переменная isSelectedType может быть final, потому что окончательные коллекции могут увеличиваться или уменьшаться. Только постоянные коллекции не позволят вам ни увеличиваться, ни уменьшаться.

Что тебе необходимо сделать:

class ToggleButtonsList extends StatefulWidget {
  ToggleButtonsList({this.type, this.stringList});

  final String type;
  final List<String> stringList;

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

class _ToggleButtonsListState extends State<ToggleButtonsList> {
  List<bool> isSelectedType = [];

  @override
  Widget build(BuildContext context) {
   
   
  }
}
person Esen Mehmet    schedule 05.10.2020
comment
Я считаю, что, хотя вы можете сделать список окончательным и тем самым успокоить компилятор, это все равно неправильно (по причинам, описанным в моем ответе) - person Lesiak; 05.10.2020

Виджеты с сохранением состояния и без состояния должны быть неизменными. Это обеспечивается @immutable в классе Widget.

См. Flutter: изменяемые поля в виджетах без сохранения состояния:

У виджетов без сохранения состояния должны быть только поля final, без исключений. Причина: когда родительский виджет перестраивается по какой-либо причине (поворот экрана, анимация, прокрутка ...), вызывается build метод родительского виджета, который вызывает реконструкцию всех виджетов.

Классы extension StatefulWidget должны следовать тому же правилу, потому что они также реконструируются. Только состояние, которое может содержать изменяемые поля, сохраняется во время жизни виджета в дереве макета.

person Lesiak    schedule 05.10.2020