flutterdartstateless

Stateless and Stateful widget, can i use both?


Is it possible to combine the two widgets? Now I'm studying flutter and if I want to keep my AppBar fixed or something else. Can I have both widgets? If it's possible, should I use the build widget on both?

I haven't tried it yet because I don't understand when I should use the build() function. But I saw that Stateless is when there are no changes in the state of the screen and Stateful when there are changes.


Solution

  • You can combine both of Stateful and Stateless widget. This is better to control build() costs. This is a example: You have a screen with a list of items and quantity for each item. At the trailing of item, you have a button add more to increase quantity of item by one. This is solution for this:

    Stateless widget (screen shows list of items)

    import 'package:demoapp/have_state.dart';
    import 'package:flutter/material.dart';
    
    class NoState extends StatelessWidget {
      const NoState({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: List.generate(
                5,
                (index) => HaveState(title: 'item $index'),
              ),
            ),
          ),
        );
      }
    }
    

    Stateful widget (item hold state itself)

    import 'package:flutter/material.dart';
    
    class HaveState extends StatefulWidget {
      const HaveState({
        super.key,
        required this.title,
      });
    
      final String title;
    
      @override
      State<StatefulWidget> createState() => _State();
    }
    
    class _State extends State<HaveState> {
      int state = 0;
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.all(24),
          child: Center(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('${widget.title} quantity: ${state.toString()}'),
                TextButton(
                  onPressed: () => setState(() {
                    state += 1;
                  }),
                  child: const Text('add more'),
                )
              ],
            ),
          ),
        );
      }
    }
    

    When you click add more button, only HaveState item will be rebuit, not entire NoState widget. It takes you more controls your build() method.