jptsetung
jptsetung

Reputation: 9156

Trying to access state from widget, probably using wrong design

I'm learning flutter and trying to make a kind of MutableImage widget. The idea is to make a MutableImage StatefulWidget that would rebuild when a new image is provided. I try to avoid rebuilding the whole widget tree each time the image is changed because that seems overkill, and I plan to update the image several times per second. So I want to rebuild only that MutableImage widget.

So here is the code I have, with comments to explain where I'm stuck :

class MutableImage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MutableImageState();
  }

  void updateImage(List<int> bytes) {
    // !!!!!! Would like to call this method here, but state is not available from Widget, which means I want to do something wrong, but not sure exactly how I should do it...
    // this.state.updateImage(bytes);
  }
}
class MutableImageState extends State<MutableImage> {
  List<int> _bytes;
  void updateImage(List<int> bytes) {
    setState(() {
      _bytes=bytes;
    });
  }

  @override
  Widget build(BuildContext context) {
    if ((_bytes==null)||(_bytes.length==0)) {
      return Center(child: CircularProgressIndicator());
    }
    return Image.memory(_bytes);
  }
}

Then the idea was to use this widget like this for example in another stateful widget

MutableImage _mutableImage;
@override
Widget build(BuildContext context) {
  if (_mutableImage == null) _mutableImage=MutableImage();
  return : Row( //using Row as an example, the idea is that the mutable Image is deep into a tree of widgets, and I want to rebuild only _mutableImage when image changes, not all widgets.
    children : <Widget>[
      child0, child1, _mutableImage, child3, child4
    ]
  );
}

void updateImage(List<int> bytes) {
  _mutableImage?.updateImage(bytes);
}

So is there a good way to do this ? I'm quite confused, thx for any help/hint.

Upvotes: 0

Views: 26

Answers (1)

Christopher Moore
Christopher Moore

Reputation: 17123

This is a place for an application of a GlobalKey. In the parent Widget of MutableImage make a global key and pass that to MutableImage. With that key you can access MutableImage state by using .currentState on the key and calling updateImage.

You'll have to add key as an argument of the MutableImage constructor and call super(key: key). updateImage should also be moved the the state of MutableImage.

Key:

final GlobalKey<MutableImageState> _imageKey = GlobalKey<MutableImageState>();

Pass the key:

MutableImage(key: _imageKey);

Access the state:

_imageKey.currentState.updateImage();

Upvotes: 1

Related Questions