How to use a Checkbox to change text in Flutter/Dart using an array/list (troubles with onChanged/setState)

177

From ChangeText widget, you are calling setState mean it will only change the UI within ChangeText widget. However, Text reflect need to happened on MyHomePage. You can use global key to change the parent state or just use callback method like

class ChangeText extends StatefulWidget {
  final Function callBack;
  const ChangeText({
    Key? key,
    required this.callBack,
  }) : super(key: key);

........
    onChanged: (value) {
          setState(() {
            boxChecked = value!;
            if (boxChecked) {
              t = 1;
            } else if (!boxChecked) {
              t = 0;
            }
          });
          widget.callBack();
        },

and use like

              child: ChangeText(
                callBack: () {
                  setState(() {});
                },
              ),

Full Widgets


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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'alternate text code',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'alternate text'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Divider(),
            Container(
              width: MediaQuery.of(context).size.width / 1.2,
              child: Text(
                'I am having trouble getting some code to work, i have tried '
                'a lot of things but cant work it out.'
                'I would like the check box to change the line of text below',
              ),
            ),
            Divider(),
            Container(
              width: MediaQuery.of(context).size.width / 1.2,
              child: ChangeText(
                callBack: () {
                  setState(() {});
                },
              ),
            ),
            Divider(),
            Container(
              width: MediaQuery.of(context).size.width / 1.2,
              child: Text(
                'you' + textChange[t] + 'a App Developer.',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

bool boxChecked = false;

class ChangeText extends StatefulWidget {
  final Function callBack;
  const ChangeText({
    Key? key,
    required this.callBack,
  }) : super(key: key);

  @override
  State<ChangeText> createState() => _ChangeText();
}

var textChange = [" could be ", " have become "];
int t = 0;

class _ChangeText extends State<ChangeText> {
  @override
  Widget build(BuildContext context) {
    return
        // Expanded(
        //   child:

        Container(
      child: CheckboxListTile(
        title: const Text(
          'learn Flutter',
          style: TextStyle(fontSize: 14),
        ),
        value: boxChecked,
        onChanged: (value) {
          setState(() {
            boxChecked = value!;
            if (boxChecked) {
              t = 1;
            } else if (!boxChecked) {
              t = 0;
            }
          });
          widget.callBack();
        },
      ),
      // ),
    );
  }
}
Share:
177
Siddharth Mehra
Author by

Siddharth Mehra

I know nothing but want to know everything!!!

Updated on January 01, 2023

Comments

  • Siddharth Mehra
    Siddharth Mehra over 1 year

    Thanks in advance, I am fairly new to this and have followed a few tutorials and read countless posts here.

    I am working on a personal project and have struck a dead end.

    I wish to change the text within a text widget by use of a checkbox, in essence turning it on and off. Unfortunately what at first seemed simple has driven me insane for the last week or so, I apologize if this has been answered but I can't find the help I need, I have found things similar but nothing has worked so far.

    I'm trying to change my int value with an onchanged and set staff function with a list/array and an int value, I effectively want to set the value from 0 to 1 and then back again.

    var textChange = [" could be ", " have become "];
    int t = 0;
    

    with;

    onChanged: (value) {
                    setState(() {
                      boxChecked = value!;
                      if (boxChecked) {
                        t = 1;
                      } else if (!boxChecked){
                        t = 0;
                      }
                      }
                    );
                  },
    

    I have made sure I am extending a Stateful Widget tried setting up different functions and methods to pass through, I have tried using a material button instead of a checkbox but still hit the same issue. I have tried a few different ways to write my onset function including something as simple as [t++ or t = (d + 1) % textChange.length;] but these would ultimately end in error once the int = >2, but I couldn't even get the value of my int to change. If I changed it manually and run the program, it works. however, I can't seem to get my onchanged and set state code to affect my array or int. I even had my original array as List, changed it to var in hopes it would make it mutable.

    I hope I said that right, I am clearly missing something but I've looked at so much I'm just lost.

    Below is the code I have used with the fat trimmed from the rest of my project. I'm using android studios with the latest updates.

    Thanks for your help and time.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'alternate text code',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'alternate text'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, required this.title}) : super(key: key);
    
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Divider(),
                Container(
                  width: MediaQuery.of(context).size.width / 1.2,
                  child:
                  Text(
                    'I am having trouble getting some code to work, I have tried '
                    'a lot of things but can't work it out.'
                    'I would like the check box to change the line of text below,
                  ),
                ),
                Divider(),
                Container(
                  width: MediaQuery.of(context).size.width / 1.2,
                  child:
                    ChangeText(),
                ),
                Divider(),
                Container(
                  width: MediaQuery.of(context).size.width / 1.2,
                  child:
                  Text(
                    'you' + textChange[t] + 'a App Developer.',
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    bool boxChecked = false;
    
    class ChangeText extends StatefulWidget {
      const ChangeText({Key? key}) : super(key: key);
    
      @override
      State<ChangeText> createState() => _ChangeText();
    }
    
    var textChange = [" could be ", " have become "];
    int t = 0;
    
    class _ChangeText extends State<ChangeText> {
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child:
          Container(
                child: CheckboxListTile(
                  title: const Text('learn Flutter', style: TextStyle(fontSize: 14),),
                  value: boxChecked,
                  onChanged: (value) {
                    setState(() {
                      boxChecked = value!;
                      if (boxChecked) {
                        t = 1;
                      } else if (!boxChecked){
                        t = 0;
                      }
                      }
                    );
                  },
                ),
          ),
        );
      }
    }
    
  • Admin
    Admin over 2 years
    Thankyou so much, the code you provided fixed my issue. being new to this i still dont quite understand how it worked, im not sure what a global key is (more learning). Atleast iknow what my issue was and now what to read up on. Simply put: The required.this added to the ChangeText class allows for the setstate to be passed to the homepage. is this correct?
  • Yeasin Sheikh
    Yeasin Sheikh over 2 years
    Also, in the future, you may always choose state management for these cases.