skip to Main Content

I’m trying to create a simple checkbox using two images and the Inkwell widget. Tapping on it it should swap the image.

It properly outputs "tapped" in the debug console, but the image is not changing even if I used the setState() function.

Any idea why it’s not working? Thank you

import 'package:flutter/material.dart';

class CustomCheckbox extends StatefulWidget {
  const CustomCheckbox({super.key});

  @override
  State<CustomCheckbox> createState() => _CustomCheckboxState();
}

class _CustomCheckboxState extends State<CustomCheckbox> {
  @override
  Widget build(BuildContext context) {
    var imgName = 'images/checkbox_off.png';
    return InkWell(
      onTap: () {
        print("tapped");
        //change the state of the image to checked  or unchecked
        setState(() {
          if (imgName == 'images/checkbox_off.png') {
            imgName = 'images/checkbox_on.png';
          } else {
            imgName = 'images/checkbox_off.png';
          }
        });
      },
      child: Container(
          width: 20.0,
          height: 20.0,
          decoration: BoxDecoration(
              image: DecorationImage(
                  fit: BoxFit.fill, image: AssetImage(imgName)))),
    );
  }
}

2

Answers


  1. Chosen as BEST ANSWER

    I was able to make it work moving the declaration of the var imgName outside the Widget Build. I also created a specific function to update the image, but this was not strictly necessary. Can somebody explain why it's working now?

    import 'package:flutter/material.dart';
    
    class CustomCheckbox extends StatefulWidget {
      const CustomCheckbox({super.key});
    
      @override
      State<CustomCheckbox> createState() => _CustomCheckboxState();
    }
    
    class _CustomCheckboxState extends State<CustomCheckbox> {
      var imgName = 'images/checkbox_off.png';
    
      void changeImage() {
        setState(() {
          if (imgName == 'images/checkbox_off.png') {
            imgName = 'images/checkbox_on.png';
          } else {
            imgName = 'images/checkbox_off.png';
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: () {
            print("tapped");
            //change the state of the image to checked  or unchecked
            changeImage();
          },
          child: Container(
              width: 20.0,
              height: 20.0,
              decoration: BoxDecoration(
                  image: DecorationImage(
                      fit: BoxFit.fill, image: AssetImage(imgName)))),
        );
      }
    }
    

  2. In your original implementation the variable was local to the build method. That meant that every time the build method was called the imgName variable was created and initialized to ‘images/checkbox_off.png’. State variables should be in the scope of the State class. Here’s one tutorial to help you understand this better: https://toastguyz.com/dart/dart-variable-scope

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