Force Stack для воссоздания собственного виджета

У меня есть стек из двух пользовательских виджетов, которые оба расположены:

  1. ProfileCard
  2. ProfileCardDummy

ProfileCard: этот пользовательский Stateful Widget является виджетом первого стека, стек сверху. Этот виджет Рис Увольняется.

ProfileCardDummy: этот пользовательский виджет без сохранения состояния является фоновым виджетом стека.

Таким образом, виджет ProfileCard находится вверху стека, а остальные фоновые стеки - это ProfileCardDummy.

Мой код выглядит примерно так:

return Stack(
    alignment: AlignmentDirectional.center,
    children:
    state.profileCards.map((ProfileCardModel card) {

        backCardWidth += 10.0;
        backBottom -= decrementalBottom;

        if (state.profileCards.indexOf(card) ==
            state.profileCards.length - 1) {
            return BlocProvider < ProfileCardBloc > (
                bloc: _profileCardBloc,
                child: ProfileCard(
                    isBack: 0,
                    bottom: initialBottom,
                    cardModel: card,
                    rotation: 0.0,
                    skew: 0.0,
                    img: image1,
                    addCard: () {},
                    onPressed: () {},
                ),
            );
        } else {
            return ProfileCardDummy(
                card,
                image2,
                backBottom,
                backCardWidth,
            );
        }
    }).toList()
);

Вся магия происходит в ProfileCard, где я выбираю содержимое карты (в основном кнопки), используя шаблон BloC.

Я отправляю событие блока на конструктор состояния ProfileCard. Что-то вроде:

class _ProfileCardState extends State<ProfileCard> {
  final VoteButtonBloc _voteButtonBloc = VoteButtonBloc();


  _ProfileCardState(){
    print("Dispatching ${widget.cardModel}");
    _voteButtonBloc.dispatch(FetchButtons(widget.cardModel));
  }
...
...

Проблема в том, что когда я запускаю код, первая ProfileCard показывает свои кнопки правильно. Теперь, когда я отклоняю его, отображается вторая ProfileCard, но с кнопками первой ProfileCard (той, которую я отклонил).

После нескольких часов отладки я заметил, что конструкторProfileCard (_ProfileCardState ()) вызывается только на первой карте. Другие карты наследуют кнопки первого класса.

В документации стека сказано:

If you reorder the children in this way, consider giving the children non-null keys.
These keys will cause the framework to move the underlying objects for the children to their new locations rather than recreate them at their new location.

Моя ProfileCard принимает ключ в качестве аргумента (так как он расширяет StatefulWidget), но я не передаю никакой ключ. Передача Ключа решит это? Как передать уникальный ключ?:P

Есть ли способ заставить воссоздание виджета заставить конструктор снова вызываться и, таким образом, правильно выбирать кнопки?

1 ответ

Решение

Обо всем по порядку. Когда у вас есть те же виджеты в списке, Flutter не будет знать, изменили ли они порядок или нет, вот где key может помочь вам.

Чтобы увидеть, как использовать ключи, вы можете проверить здесь и это видео, которое довольно хорошо объясняет для списка сценариев, где вы хотите изменить порядок элемента, например.

setState позвоню build в состоянии виджетов присутствует уже в дереве, но не будет вызывать конструктор или initStateэто только когда виджет фактически вставлен в дерево. Когда родитель меняется, Flutter будет искать изменения в своих дочерних элементах и ​​вызывает didUpdateWidget метод для каждого состояния виджета, где вы можете переопределить и фактически сравнить изменения старого виджета с новым.

Поскольку вы всегда хотите восстановить виджет, просто дайте ему UniqueKey в качестве таких

ProfileCard(key: UniqueKey());

Это скажет Flutter, что вы на самом деле создаете новый объект, а не повторно используете старый.

Другие вопросы по тегам