Home > Mobile >  Update variable outside a widget in Flutter?
Update variable outside a widget in Flutter?

Time:01-04

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.)

CodePudding user response:

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 !'),
    );
  }
}

CodePudding user response:

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 !'),
    );
  }
}
  • Related