Попытка получить доступ к состоянию из виджета, возможно, используя неправильный дизайн - PullRequest
0 голосов
/ 24 апреля 2020

Я учусь трепетать и пытаюсь создать виджет MutableImage. Идея заключается в создании MutableImage StatefulWidget, который будет перестраиваться при предоставлении нового изображения. Я стараюсь не перестраивать все дерево виджетов каждый раз, когда изображение меняется, потому что это кажется излишним, и я планирую обновлять изображение несколько раз в секунду. Поэтому я хочу перестроить только этот виджет MutableImage.

Итак, вот мой код с комментариями, чтобы объяснить, где я застрял:

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);
  }
}

Тогда была идея использовать это такой виджет, например, в другом виджете с состоянием

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);
}

Так есть ли хороший способ сделать это? Я в замешательстве, спасибо за любую помощь / подсказку.

1 Ответ

1 голос
/ 24 апреля 2020

Это место для подачи заявления GlobalKey. В родительском виджете MutableImage создайте глобальный ключ и передайте его MutableImage. С помощью этого ключа вы можете получить доступ к состоянию MutableImage, используя клавишу .currentState и вызвав updateImage.

Вам нужно будет добавить ключ в качестве аргумента конструктора MutableImage и вызвать super(key: key). updateImage также следует переместить в состояние MutableImage.

Ключ:

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

Передать ключ:

MutableImage(key: _imageKey);

Доступ к состоянию:

_imageKey.currentState.updateImage();
...