Zhicheng Zhang
Zhicheng Zhang

Reputation: 69

How to avoid warning when defining member in widget?

Here is my code.

import 'package:flutter/material.dart';

class Home extends StatelessWidget {
  Map _parameters;

  Home([Map params]) {
    _parameters = params;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          children: [
            Text(_parameters.toString()),
          ],
        ),
      ),
    );
  }
}

IDE says there is a warning.

info: This class (or a class which this class inherits from) is marked as '@immutable', but one or more of its instance fields are not final: Home._parameters (must_be_immutable at [hello_flutter_boost] lib/page/home.dart:6)

Here is a problem. I have to define _parameters to store parameter from Home() (constructor) so the widget can get parameters from outside. But it causes a warning.

Is there any way to avoid the warning?

(related issue in GitHub: https://github.com/flutter/flutter/issues/36899)

Upvotes: 1

Views: 656

Answers (3)

user3582315
user3582315

Reputation: 209

I've come across the same issue and neither Saed's nor Eric's answers are totally satisfying IMHO (I'm no Dart/Flutter expert).

Using a StatefulWidget while your widget won't really change over time, which seems to be OP's case, comes with a performance drop.

Using constructor's initializer list or syntactic sugar won't work if your instance variable needs to be initialized with a more complex code than just this.x = x. And you won't be able to initialize the variable in the constructor's body neither of course so you're stuck.

The only workaround I've found is to compute the value of the instance variable outside the widget and pass it as an argument to the widget. I understand the philosophy behind the StatelessWidget being @immutable but in some cases it breaks the concept of widget being dedicated pieced of work.

Upvotes: 1

Saed Nabil
Saed Nabil

Reputation: 6861

StatefulWidget

You should not mutate variables inside your stateless class it is by design immutable that is why there is another type of widget that can permit state mutation which is the stateful widget

so you need to convert your stateless widget into stateful one.

Code:

class Home extends StatefulWidget {
  final Map parameters;

  Home({this.parameters});

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

class _HomeState extends State<Home> {
  var _paramater ;
  @override
  void initState() {
    super.initState();
    _paramater = widget.parameters;
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          children: [
            Text(_paramater.toString()),
          ],
        ),
      ),
    );
  }
}

Upvotes: 1

Eric Duffett
Eric Duffett

Reputation: 1684

StatelessWidget

Put the word "final" in front of your map declaration, and change the constructor.

import 'package:flutter/material.dart';

class Home extends StatelessWidget {
  final Map _parameters;

  Home([this._parameters]);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          children: [
            Text(_parameters.toString()),
          ],
        ),
      ),
    );
  }
}

Upvotes: 1

Related Questions