Home > Net >  Flutter - How to Extract Widget with onPressed setState inside?
Flutter - How to Extract Widget with onPressed setState inside?

Time:09-17

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',
      ),
    ),
  ),

CodePudding user response:

Setstate is related to the widget you want to refresh its state. If you extract it to another place, then setState refers to the state of the new widget.

In your case, the setState will only change the state of the container encapsulating your widget which you are trying to extract and its children, it doesn't migrate upward.

Unless, you look for the state of the widget you want, using exact type, and then trigger the state there, but this is overkill, a lot harder, requires more code, than what you currently have.

CodePudding user response:

You can use VoidCallback on extract widget to get onPressed event

class MyContainer extends StatelessWidget {
  final VoidCallback onTap;
  const MyContainer({
    Key? key,
    required this.onTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextButton(
        onPressed: onTap,
        child: Text(
          'Button 001',
        ),
      ),
    );
  }
}

And use like

          MyContainer(
            onTap: () {
              print("tapped");

              setState(() {
                calculate();
              });
            },
          ),
  • Related