skip to Main Content

I’ve created a stateful Widget as my main page with a String variable, textToDisplay.

import 'package:flutter/material.dart';

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

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  String textToDisplay = 'Choose option';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Text(
              '$textToDisplay',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(
              height: 20,
            ),
            Choices(onTap: (){setState(() {
              textToDisplay =
            });},),
          ],
        ),
      ),
    );
  }
}

I have then created a stateless widget in another dart file called Choices().

class Choices extends StatelessWidget {
  Choices({required this.onTap});

  final VoidCallback? onTap;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: 20,
        ),
        Buttons(text: 'Option A', onTap: onTap),
        SizedBox(
          height: 10,
        ),
        Buttons(text: 'Option B', onTap: onTap),
      ],
    );
  }
}

and in this are 2 stateless widget buttons which have the ontap gesture.

class Buttons extends StatelessWidget {
  Buttons({required this.text, required this.onTap});

  final String text;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      child: Container(
        color: Colors.green,
        width: 100,
        height: 40,
        child: Text(
          text,
        ),
      ),
    );
  }
}

I can pass the onTap gesture up the tree but what I need to do is when a button is pressed, it updates the variable, textToDisplay to display option A or Option B, depending on which button has been pressed.

I thought i could do this with a stateless widget (Choices()) because the data isn’t chageing it is only being read

any help would be greatly appreciated.

2

Answers


  1. One way of updating the top-level string is the create your own Callback using ValueChanged.

    Here is a complete working example:

    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: Scaffold(
            body: Center(
              child: MainPage(),
            ),
          ),
        );
      }
    }
    
    class MainPage extends StatefulWidget {
      const MainPage({Key? key}) : super(key: key);
    
      @override
      State<MainPage> createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage> {
      String textToDisplay = 'Choose option';
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              children: [
                Text(
                  textToDisplay,
                  style: TextStyle(fontSize: 20),
                ),
                SizedBox(
                  height: 20,
                ),
                Choices(
                  onTap: (val) {
                    setState(() {
                      textToDisplay = val;
                    });
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class Choices extends StatelessWidget {
      Choices({required this.onTap});
    
      final ValueChanged? onTap;
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            SizedBox(
              height: 20,
            ),
            Buttons(
              text: 'Option A',
              onTap: onTap,
            ),
            SizedBox(
              height: 10,
            ),
            Buttons(text: 'Option B', onTap: onTap),
          ],
        );
      }
    }
    
    class Buttons extends StatelessWidget {
      Buttons({required this.text, required this.onTap});
    
      final String text;
      final ValueChanged? onTap;
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: () {
            if (onTap != null) {
              onTap!(text);
            }
          },
          child: Container(
            color: Colors.green,
            width: 100,
            height: 40,
            child: Text(
              text,
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. you can use function with parameter

    class MainPage extends StatefulWidget {
      const MainPage({Key? key}) : super(key: key);
    
      @override
      State<MainPage> createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage> {
      String textToDisplay = 'Choose option';
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              children: [
                Text(
                  textToDisplay,
                  style: const TextStyle(fontSize: 20),
                ),
                const SizedBox(
                  height: 20,
                ),
                Choices(
                  onTap: (text) {
                    _chageText(text);
                  },
                ),
              ],
            ),
          ),
        );
      }
    
      void _chageText(String text) {
        setState(() {
          textToDisplay = text;
        });
      }
    }
    
    class Choices extends StatelessWidget {
      const Choices({super.key, required this.onTap});
    
      final Function(String text) onTap;
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            const SizedBox(
              height: 20,
            ),
            Buttons(text: 'Option A', onTap: () => onTap('Option A')),
            const SizedBox(
              height: 10,
            ),
            Buttons(text: 'Option B', onTap: () => onTap('Option B')),
          ],
        );
      }
    }
    
    class Buttons extends StatelessWidget {
      const Buttons({super.key, required this.text, required this.onTap});
    
      final String text;
      final VoidCallback? onTap;
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: onTap,
          child: Container(
            color: Colors.green,
            width: 100,
            height: 40,
            child: Text(
              text,
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search