Classe marquée comme @immutable, champ d'instance non final à l'aide de StatefulWidget

Oct 05 2020

J'ai un widget sans état appelé ToggleButtonsList et l'un de mes champs d'instance, isSelectedType, n'est pas défini sur final. Voici l'avertissement que je reçois à cause de ceci:

"Cette classe (ou une classe dont cette classe hérite) est marquée comme '@immutable', mais un ou plusieurs de ses champs d'instance ne sont pas définitifs: ToggleButtonsList.isSelectedType"

Voici une partie de mon code:

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) {
   
   
  }
}

Ma question: je pensais que les champs d'instance devaient être définis sur final uniquement pour les widgets sans état, PAS pour les widgets avec état . Est-ce vrai? Est-ce un avertissement dont je devrais m'inquiéter puisque je n'utilise pas de StatelessWidget ou puis-je l'ignorer? Mon application semble fonctionner parfaitement bien lorsque j'ignore l'avertissement.

La lecture de la partie "ou une classe dont cette classe hérite" de l'avertissement m'a incité à rechercher dans mon projet tous les StatelessWidgets dont cette classe peut hériter et le seul StatelessWidget que j'ai dans mon projet provient de mon 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(),
    );
  }
}

Changer ma classe MyApp en StatefulWidget n'a pas supprimé l'avertissement.

Réponses

2 EsenMehmet Oct 05 2020 at 12:00

Je pense à ton mix Stateet à ta StatefulWidgetclasse. La Widgetclasse elle-même est immutableet les deux StatelessWidgetet StatefulWidgets'étend de la Widgetclasse.

Dans votre cas spécifique, la isSelectedTypevariable peut être final, car les collections finales peuvent augmenter ou diminuer. Seules les collections constantes ne vous permettront pas de grandir ou de diminuer.

Qu'as tu besoin de faire:

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) {
   
   
  }
}
1 Lesiak Oct 05 2020 at 12:00

Les widgets avec état et sans état doivent être immuables. Ceci est appliqué par @immutableon Widgetclass.

Voir Flutter: Champs mutables dans les widgets sans état :

Les widgets sans état ne doivent avoir que des champs finaux, sans exception . Raison: Lorsque le widget parent est reconstruit pour une raison quelconque (rotation de l'écran, animations, défilement ...), la buildméthode du parent est appelée, ce qui provoque la reconstruction de tous les widgets.

Les classes étendues StatefulWidgetdoivent suivre la même règle, car elles sont également reconstruites. Seul l'état, qui peut contenir des champs mutables, est conservé pendant la durée de vie du widget dans l'arbre de mise en page.