Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with setstate #1

Closed
Bernhard602 opened this issue Jan 18, 2022 · 4 comments
Closed

Problems with setstate #1

Bernhard602 opened this issue Jan 18, 2022 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@Bernhard602
Copy link

I try to change the panelHeight and update the screen by setstate, but the StickIt widget seems to be corrupt as soon as I use setstate

Error after using after setstate:
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value
E/flutter (18051): #0 _StickItState._exportImage (package:stick_it/src/stick_it.dart:192:56)
E/flutter (18051): #1 StickIt.exportImage (package:stick_it/src/stick_it.dart:94:51)

code:

  StickIt _stickIt;
  bool showStickerBar=true;

  @override
  Widget build(BuildContext context) {
    
    _stickIt = StickIt(
      child: Image.file(widget.image, fit: BoxFit.cover),
      panelHeight:
      showStickerBar==true
          ? 200
          : 0,
      stickerList: [
        Image.asset('assets/stickers/test1.png'),
        Image.asset('assets/stickers/test2.png'),
      ],
    );

    return new Scaffold(
      appBar: PreferredSize(
        preferredSize: Size(double.infinity, 80),
        child: Stack(
          children: <Widget>[
                  InkWell(
                    onTap: () async {

                      final imageInUnit8List = await _stickIt.exportImage();
                      final Directory tempDir = await getTemporaryDirectory();
                      File imageWithSticker = await File('${tempDir.path}/image.png').create();
                      imageWithSticker.writeAsBytesSync(imageInUnit8List);

                    },
                    child: Text('next',
                      style: TextStyle(
                        fontSize: 17,
                      ),
                    ),
                  ),
                ],
              ),
            ),
      body: Center(
        child: Container(
          child: _stickIt,
        ),
      ),
      floatingActionButton:
            FloatingActionButton(
              onPressed: () {
                if (showStickerBar==true){
                  setState(() {
                    showStickerBar = false;
                  });
                }else if (showStickerBar==false){
                  setState(() {
                    showStickerBar = true;
                  });
                }
              },
              child: new Icon(
                Icons.emoji_emotions_outlined,
              ),
            ),

      

_stickIt
,
I do not use null safety (unfortunately that is not possible)

thanks for help

@NicolasDurant NicolasDurant self-assigned this Jan 19, 2022
@NicolasDurant NicolasDurant added the bug Something isn't working label Jan 19, 2022
@NicolasDurant
Copy link
Owner

I will try to reproduce the issue and see, if I can help

@NicolasDurant NicolasDurant added question Further information is requested and removed question Further information is requested labels Jan 20, 2022
@NicolasDurant
Copy link
Owner

NicolasDurant commented Jan 20, 2022

Adding a key of type UniqueKey should do the trick for you. I was able to reproduce your issue in a fresh project, when leaving that out. I also tested running it without null safety so here you go:

StickIt(
   key: UniqueKey(),
   ...

I didn't write the package myself, but it is reliant on a key to generate an image out of your sticker constellation. As long as the widget is used stateless with nonchanging values, it shouldn't be a problem, but since you try to adjust the panelHeight dynamically with changing the state, the build of StickIt will be recalled, which leads to the key being null and creating the issue. I think usually one shouldn't manage the state about keys like the original owner does, but I am not too deep in that topic either. Here's the full class, (I had to use an appbar, because I couldnt click your button):

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

  @override
  _ReproduceTestState createState() => _ReproduceTestState();
}
class _ReproduceTestState extends State<ReproduceTest> {
  late StickIt _stickIt;
  bool showStickerBar = true;

  @override
  Widget build(BuildContext context) {
    _stickIt = StickIt(
      /// The KEY point (see what I did there? :p)
      /// Without a key you can't change the state without breaking the widget
      key: UniqueKey(),
      /// Change the image back to yours
      child: Image.asset('assets/simplest-example', fit: BoxFit.cover),
      panelHeight: showStickerBar ? 200 : 0,
      stickerList: [
        /// Change the stickers back to yours
        Image.asset('assets/icons8-anubis-48.png'),
        Image.asset('assets/icons8-anubis-48.png'),
      ],
    );
   return Scaffold(
      appBar: AppBar(
        title: const Text('Reproduce'),
        actions: [
          InkWell(
            onTap: () async {
              final imageInUnit8List = await _stickIt.exportImage();
              final Directory tempDir = await getTemporaryDirectory();
              File imageWithSticker = await File('${tempDir.path}/image.png').create();
              imageWithSticker.writeAsBytesSync(imageInUnit8List);

              /// That was just a test to see, if the image is actually saved to the gallery.
              /// It worked.
              // GallerySaver.saveImage(imageWithSticker.path, albumName: 'Stick It').then((value) {
              //   ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
              //     content: Text("Image saved in the gallery album 'Stick It', go take a look!"),
              //   ));
              // });
            },
            child: const Text(
              'next',
              style: TextStyle(
                fontSize: 17,
              ),
            ),
          )
        ],
      ),
      body: Center(
        child: Container(
          child: _stickIt,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            showStickerBar = !showStickerBar;
          });
        },
        child: const Icon(
          Icons.emoji_emotions_outlined,
        ),
      ),
    );
  }
}

Also don't forget, if you use the packages I used in my example for saving the images, you have to go through the installation processes of the packages. Some of them require changing your Info.plist or AndroidManifest.xml.

@Bernhard602
Copy link
Author

it works!

huge thanks @NicolasDurant 🥇 👍
you saved my day

@NicolasDurant
Copy link
Owner

it works!

huge thanks @NicolasDurant 🥇 👍 you saved my day

Glad it works now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants