1

Is it possible to update a variable outside a widget while calling it ? Here's an example :

class Widget1 extends StatefulWidget {

  @override
  State<Widget1> createState() => _Widget1State();
}

class _Widget1State extends State<Widget1> {
  String example = 'A';

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Text(example),
      Widget2(example: example)
    ],);
  }
}
class Widget2 extends StatefulWidget {
  final String example;

  Widget2({required this.example});

  @override
  State<Widget2> createState() => _Widget2State();
}

class _Widget2State extends State<Widget2> {

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => setState(() {
        widget.example = 'B'
      }),
      child: Text('update !'),
    );
  }
}

The idea here is that I want to update example using a button outside the widget.

This code is not working : example = 'A' no matter if I click the button or not, but I don't understand why since I'm calling the same variable.

Is there a simple solution to achieve this ? (by simple, I mean without the need of Provider or else.)

3 Answers 3

3

You can use callback method. Parent widget needed to updated, so setState is needed to be trigger on Widget1.

class Widget1 extends StatefulWidget {
  @override
  State<Widget1> createState() => _Widget1State();
}

class _Widget1State extends State<Widget1> {
  String example = 'A';

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(example),
        Widget2(
          example: example,
          callback: (p0) {
            setState(() {
              example = p0;
            });
          },
        ),
      ],
    );
  }
}

class Widget2 extends StatefulWidget {
  final String example;
  final Function(String) callback;
  Widget2({
    required this.example,
    required this.callback,
  });

  @override
  State<Widget2> createState() => _Widget2State();
}

class _Widget2State extends State<Widget2> {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        widget.callback("new data");
      },
      child: Text('update !'),
    );
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Note:for project level data handling, you may use state-management like provider/riverpod/bloc....
Of course... I was asking for a small feature that doesn't require that much work. Anyway, your code works fine, thank you !!
0

You can use Notifiers, here is an example:

import 'package:flutter/material.dart';

class ExampleNotifier with ChangeNotifier {
  String example = 'A';

  ExampleNotifier();    

  setText(string x) {
    example = x;
    notifyListeners();

  }    
}

and then use it like:

class Widget1 extends StatefulWidget {
  @override
  State<Widget1> createState() => _Widget1State();
}

class _Widget1State extends State<Widget1> {

  @override
  Widget build(BuildContext context) {

var exampleNotifier = Provider.of<ExampleNotifier>(context);
    return Column(
      children: [
        Text(exampleNotifier.example),
        Widget2(),
      ],
    );
  }
}

class Widget2 extends StatefulWidget {

  @override
  State<Widget2> createState() => _Widget2State();
}

class _Widget2State extends State<Widget2> {
  @override
  Widget build(BuildContext context) {

    var exampleNotifier = Provider.of<ExampleNotifier>(context, listen: false);

    return ElevatedButton(
      onPressed: () {
        exampleNotifier.setText('B');
      },
      child: Text('update !'),
    );
  }
}

Comments

0

If you want to use setState, you can use this

class Widget1 extends StatefulWidget {
  @override
  State<Widget1> createState() => _Widget1State();
}

class _Widget1State extends State<Widget1> {
  String example = 'A';

  void changeExample() {
    setState(() => example = "B");
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [Text(example), Widget2(changeExample: changeExample)],
    );
  }
}

class Widget2 extends StatelessWidget {
  final void Function() changeExample;

  Widget2({required this.changeExample});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: changeExample,
      child: Text('update !'),
    );
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.