Home > Net >  Flutter : setState outside
Flutter : setState outside

Time:05-03

I'm new to Flutter and I just want to understand something about stateful widget. Here's a simple code that works perfectly just by switching the text color from red to blue when clicking on a button :

import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Color myColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("My app")),
        body: Column(
          children: [
            Text(
              "Just a simple text",
              style: TextStyle(color: myColor),
            ),
            FloatingActionButton(
                onPressed: () {
                  setState(() {
                    myColor =
                        (myColor == Colors.red) ? Colors.blue : Colors.red;
                  });
                  print(myColor);
                },
                child: Icon(Icons.home)),
          ],
        ));
  }
}

My question is : if I get the column outside the stateful widget and call it as a component, how and where should I rewrite the setState function ? I begin with this code and I don't know how to continue :

import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Color myColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("My app")),
        body: HomePage());
  }
}

Column HomePage()
{
return Column(
          children: [
            Text(
              "Just a simple text",
              style: TextStyle(color: myColor), // SHOULD I NOW INJECT myColor AS A PARAMETER OF HomePage ?
            ),
            FloatingActionButton(
                onPressed: () {print("WHERE TO PUT THE setState FUNCTION NOW ???")},
                child: Icon(Icons.home)),
          ],
        );
}

CodePudding user response:

Your HomePage() is just a function that returns a Column, so you can just include it within the _MyWidgetState class to be able to access the state directly, and call the setState method, like that:

import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Color myColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("My app")),
        body: HomePage());
  }


  Column HomePage(){
    return Column(
      children: [
        Text(
          "Just a simple text",
          style: TextStyle(color: myColor), // SHOULD I NOW INJECT myColor AS A PARAMETER OF HomePage ?
        ),
        FloatingActionButton(
            onPressed: () {
              setState(() {
                myColor = Colors.amber;
              });
            },
            child: Icon(Icons.home)),
      ],
    );
  }
}

CodePudding user response:

Here's a example class for how to pass data from one class to another class

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main1.dart';

void main() {
  runApp(MaterialApp(
    home: Modalbtn(),
  ));
}

class Modalbtn extends StatefulWidget {
  @override
  _ModalbtnState createState() => _ModalbtnState();
}

class _ModalbtnState extends State<Modalbtn> {
  String value = "0";
  // Pass this method to the child page.
  void _update(String newValue) {
    setState(() => value = newValue);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            IconButton(
              onPressed: () {
                showModalBottomSheet(
                    context: context,
                    builder: (BuildContext context) {
                      return Container(
                        height: 200,
                        child: Column(
                          children: [StatefulModalbtn(update: _update)],
                        ),
                      );
                    });
              },
              icon: Icon(Icons.add),
              iconSize: 20,
            ),
            Text(
              value,
              style: TextStyle(fontSize: 40),
            ),
          ],
        ),
      ),
    );
  }
}

import 'package:flutter/material.dart';

class StatefulModalbtn extends StatelessWidget {
  final ValueChanged<String> update;
  StatefulModalbtn({required this.update});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => update("100"), // Passing value to the parent widget.

      child: Text('Update (in child)'),
    );
  }
}

CodePudding user response:

If you insist of having the HomePage() function outside the class you could do this for example:

class MyWidget extends StatefulWidget {
  MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  Color myColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("My app")),
        body: HomePage(myColor, changeColor));
  }
  
  void changeColor(Color color) {
    setState((){
      myColor = color;
    });
  }
}

Column HomePage(Color color, ValueSetter<Color> change)
{
    return Column(
      children: [
        Text(
          "Just a simple text",
          style: TextStyle(color: color),
        ),
        FloatingActionButton(
            onPressed: () { change(Colors.blue);},
            child: Icon(Icons.home)),
      ],
    );
}
  • Related