0

Forgive me if this is a simple fix but I am new to Flutter and I've had trouble finding a solution. I have one stateless widget, MySpriteGame which uses SpriteWidget. I have another widget called SpriteSquare, also stateless, which I am trying to add an event handler to. I'll add the code for both at the end (minus all of the imports to maximize space).

In want to pass down a function from MySpriteGame to SpriteSquare that basically adds _whitesquare, an instance of SpriteSquare to _background, another instance of SpriteSquare. The problem I am encountering is below.

The instance member 'handleEvent' can't be accessed in an initializer.

I know this is because I cannot add a function that adds _whitesquare to _background in the initialization of those variables. If MySpriteGame were stateful, I'd probably add the listener in an initState or something. I was wondering if there was a way to add these event listeners to the SpriteSquare nodes after initialization without having to make this widget stateful?

sprite_square.dart

class SpriteSquare extends NodeWithSize {
  
  Color color;
  Function handler;

  SpriteSquare(size, this.color, this.handler) : super(size){
    userInteractionEnabled = true;
  }

  @override handleEvent(SpriteBoxEvent event) {
    handler(event);
    return true;
  }

  @override
    Future<void> paint(Canvas canvas) async {
      applyTransformForPivot(canvas);
      canvas.drawRect(
        new Rect.fromLTWH(0.0, 0.0, size.width, size.height),
        Paint()..color = color
      );
    }
}

sprite_game.dart

class MySpriteGame extends StatelessWidget {

  final _background = SpriteSquare(const Size(400.0, 400.0), const Color(0xFF000000), (e)=>handleEvent(e));
  final _whitesquare = SpriteSquare(const Size(200.0, 200.0), const Color(0xFFFFFFFF), (e)=>handleEvent(e));

  MySpriteGame({Key? key}) : super(key: key);

  handleEvent(SpriteBoxEvent event) {
    _background.addChild(_whitesquare);
    return true;
  }

  handleRemoveSelf(SpriteBoxEvent event){
    print(event);
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: 
          SpriteWidget(
            _background
          )
      ),
    );
  }
}

EDIT

I feel like I might be onto something by adding the function after the Widget build... and before the return Center.... I can do _background.handleEvent() but I'm not sure how to add the logic from the handleEvent above into this handleEvent.

Matt Croak
  • 2,788
  • 2
  • 17
  • 35
  • [Non-`late` member variables are initialized before `this` is valid](https://stackoverflow.com/a/63319094/). In your case, the simplest fix probably would be to declare those members with `late final`. – jamesdlin Oct 14 '21 at 16:01

1 Answers1

0

I am not sure if this is best practice but I was able to initialize _background with ()=>{} as the handler. Then after the Widget build... I have the line _background.handler = handleAdd; which enabled me to apply the logic in handleAdd to the handleEvent for this instance of SpriteSquare.

I am now able to add _whitesquare to the _background.

Matt Croak
  • 2,788
  • 2
  • 17
  • 35