StatefulBuilder

 

StatefulBuilder

A platonic widget that both has state and calls a closure to obtain its child widget.

The StateSetter function passed to the builder is used to invoke a rebuild instead of a typical State's State.setState.

Since the builder is re-invoked when the StateSetter is called, any variables that represents state should be kept outside the builder function.



    import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: const Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

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

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

class _MyWidgetState extends State {
  double lerp = 0;
  Color buttonColor = Colors.blue[100]!;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          StatefulBuilder(
            builder: (context, setState) {
              return InexpensiveWidget(
                color: Color.lerp(buttonColor, Colors.black, lerp)!,
                onPressed: () => setState(() {
                  lerp += 0.1;
                  if (lerp > 1) {
                    lerp = 0;
                  }
                }),
              );
            },
          ),
          // Pretend `const` is not feasible here
          // ignore: prefer_const_constructors
          ExpensiveWidget(),
        ],
      ),
    );
  }
}

class InexpensiveWidget extends StatelessWidget {
  const InexpensiveWidget({
    Key? key,
    required this.color,
    required this.onPressed,
  }) : super(key: key);

  final VoidCallback onPressed;
  final Color color;

  @override
  Widget build(BuildContext context) {
    print("              building InexpensiveWidget");
    return TextButton(
      onPressed: onPressed,
      style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all(color)),
      child: const Text("I rebuild often"),
    );
  }
}

class ExpensiveWidget extends StatelessWidget {
  const ExpensiveWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print('Painstakingly building ExpensiveWidget');
    return const Text("I'm expensive!");
  }
}
    


Post a Comment

Previous Post Next Post

Subscribe Us


Get tutorials, Flutter news and other exclusive content delivered to your inbox. Join 1000+ growth-oriented Flutter developers subscribed to the newsletter

100% value, 0% spam. Unsubscribe anytime