Force Stack для воссоздания собственного виджета - PullRequest
0 голосов
/ 04 февраля 2019

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

  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.

Я отправляю событие 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 Ответ

0 голосов
/ 04 февраля 2019

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

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

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

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

ProfileCard(key: UniqueKey());

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

...