skip to Main Content

i tried to make a checkbox for a week in flutter . and because of not writing extra code i made a widget "week" and when i run the code i can see the checkboxes but when i click on them the UI doesn’t change … i expect when i click on a ticked box => the box turns to unticked and vice versa. and this doesn’t happen and i don’t know what is the problem?? please help me …please…
thank you.

here is my whole code:and this is the UI image

import "package:flutter/services.dart";

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyPage(),
    );
  }
}

class MyPage extends StatefulWidget {
  MyPage({super.key});

  @override
  State<MyPage> createState() => _Example();
}

class _Example extends State<MyPage> {
  bool mon = true;
  bool tue = true;
  bool wed = true;
  bool thu = true;
  bool fri = true;
  bool sat = true;
  bool sun = true;

  Widget week(bool? value, String day) {
    return Padding(
      padding: const EdgeInsets.all(5.0),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(day),
            Checkbox(
                value: value,
                onChanged: (bool? new_Value) {
                  setState(() {
                    value = new_Value;
                  });
                }),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('HDBOOKS'),
        ),
        body: Center(
          child: Row(
            children: [
              week(mon, 'Mon'),
              week(tue, 'Tue'),
              week(wed, 'Wed'),
              week(thu, 'Thu'),
              week(fri, 'fri'),
              week(sat, 'sat'),
              week(sun, 'sun'),
            ],
          ),
        ));
  }
}

… i expect when i click on a ticked box => the box turns to unticked and vice versa. and this doesn’t happen and i don’t know what is the problem?? please help me …please…
thank you.

2

Answers


  1. You have created a helper function for the week widget which is not a good way to declare widgets that are able to update their state at runtime.

    Inside the helper function when you tap, the build method is called but it is not reflected in the UI part because the behaviour of the function is only to return a value or execute the code inside the function.

    There are 3 ways to solve this problem,

    1. Declare the week widget inside the build method for all days. This solution works but you have to write duplicate code many times.
    2. Wrap the week widget with a StatefulBuilder that provides a method to update the state of the widget,
    Widget week(bool? value, String day) {
      return StatefulBuilder(
        builder: (context, updatets) {
          return Padding(
            padding: const EdgeInsets.all(5.0),
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(day),
                  Checkbox(
                    value: value,
                    onChanged: (bool? new_Value) {
                      updatets(() {
                        value = new_Value;
                      });
                    },
                  ),
                ],
              ),
            ),
          );
        },
      );
    }
    

    This will solve your problem but not efficiently.

    1. Create a separate stateful widget for the week. By creating a separate widget, the widget manages its state whenever its state changes and updates its state according to the widget’s life cycle. This is an efficient, clean and maintainable solution.
    import 'package:flutter/material.dart';
    
    class Week extends StatefulWidget {
      Week({required this.day, this.value = false});
    
      bool? value;
      final String day;
    
      @override
      State<Week> createState() => _WeekState();
    }
    
    class _WeekState extends State<Week> {
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.all(5.0),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(widget.day),
                Checkbox(
                  value: widget.value,
                  onChanged: (bool? new_Value) {
                    setState(() {
                      widget.value = new_Value;
                    });
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. Please try this

    The issue in your code lies in how you are updating the state. When you pass value to the week function, it is a local variable, and changing it inside the function does not affect the state variables (mon, tue, etc.) in your _Example class.

    To fix this, you need to update the state variables (mon, tue, etc.) directly in the onChanged callback. Here’s an updated version of your code:

    import "package:flutter/material.dart";
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MyPage(),
        );
      }
    }
    
    class MyPage extends StatefulWidget {
      MyPage({super.key});
    
      @override
      State<MyPage> createState() => _Example();
    }
    
    class _Example extends State<MyPage> {
      bool mon = true;
      bool tue = true;
      bool wed = true;
      bool thu = true;
      bool fri = true;
      bool sat = true;
      bool sun = true;
    
      Widget week(bool value, String day, Function(bool) onChanged) {
        return Padding(
          padding: const EdgeInsets.all(5.0),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(day),
                Checkbox(
                    value: value,
                    onChanged: (bool? newValue) {
                      onChanged(newValue ?? false);
                    }),
              ],
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('HDBOOKS'),
          ),
          body: Center(
            child: Row(
              children: [
                week(mon, 'Mon', (newValue) {
                  setState(() {
                    mon = newValue;
                  });
                }),
                week(tue, 'Tue', (newValue) {
                  setState(() {
                    tue = newValue;
                  });
                }),
                week(wed, 'Wed', (newValue) {
                  setState(() {
                    wed = newValue;
                  });
                }),
                week(thu, 'Thu', (newValue) {
                  setState(() {
                    thu = newValue;
                  });
                }),
                week(fri, 'Fri', (newValue) {
                  setState(() {
                    fri = newValue;
                  });
                }),
                week(sat, 'Sat', (newValue) {
                  setState(() {
                    sat = newValue;
                  });
                }),
                week(sun, 'Sun', (newValue) {
                  setState(() {
                    sun = newValue;
                  });
                }),
              ],
            ),
          ),
        );
      }
    }
    
    

    This way, the onChanged callback directly updates the state variables, and the UI should reflect the changes correctly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search