I want to Extract a Widget with onPressed setState inside but I get the Message "Reference to an enclosing class method cannot be extracted."
Is there a way to do that?
I would like to divide my code into different widgets so that it remains clear. Here is simplified an example of the code:
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Calculator(),
    );
  }
}
class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
  var myValue = 0;
  void calculate() {
    myValue = 12;
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            child: TextButton(
              onPressed: () {
                setState(() {
                  calculate();
                });
              },
              child: Text(
                'Button 001',
              ),
            ),
          ),
          TextOutput(myValue: myValue),
        ],
      ),
    );
  }
}
class TextOutput extends StatelessWidget {
  const TextOutput({
    Key key,
    @required this.myValue,
  }) : super(key: key);
  final int myValue;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        myValue.toString(),
      ),
    );
  }
}
The part I want to extract into a separate widget:
  Container(
    child: TextButton(
      onPressed: () {
        setState(() {
          calculate();
        });
      },
      child: Text(
        'Button 001',
      ),
    ),
  ),
Flutter offers VoidCallback and Function(x) (where x can be a different type) for callback-style events between child and parent widgets.
Simply You can pass Function onPressed; via constructor
Here is your Extracted Container widget:
class ExtractedContainer extends StatelessWidget {
  final Function onPressed;
  const ExtractedContainer({
    Key key, @required this.onPressed,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextButton(
        onPressed: () {
          onPressed();
        },
        child: Text(
          'Button 001',
        ),
      ),
    );
  }
}
And Here How to use it:
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ExtractedContainer(onPressed: calculate,),
          TextOutput(myValue: myValue),
        ],
      ),
    );
  }
Your full code example
import 'package:flutter/material.dart';
class MyApp2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Calculator(),
    );
  }
}
class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
  var myValue = 0;
  void calculate() {
    myValue = 12;
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ExtractedContainer(onPressed: calculate,),
          TextOutput(myValue: myValue),
        ],
      ),
    );
  }
}
class ExtractedContainer extends StatelessWidget {
  final Function onPressed;
  const ExtractedContainer({
    Key key, @required this.onPressed,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextButton(
        onPressed: () {
          onPressed();
        },
        child: Text(
          'Button 001',
        ),
      ),
    );
  }
}
class TextOutput extends StatelessWidget {
  const TextOutput({
    Key key,
    @required this.myValue,
  }) : super(key: key);
  final int myValue;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        myValue.toString(),
      ),
    );
  }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With