Flutter - удаляя элемент ListView из списка, сбрасывается состояние элемента списка под удаляемым
На первой page есть список товаров, каждый можно добавить в массив объектов (избранное), который находится выше по иерархии, оттуда просто спускается setState, и вызывается в момент когда товар добавляется, то есть обновляем состояние избранных товаров. Весь массив этих избранных товаров передается на вторую page где в виде ListView они все по очереди отображаются. Но там есть кнопка "Удалить из избранного" которая вызывает setState переданный сверху , чтобы удалить объект из массива избранных, перерисовать ListView и показать что теперь в списке на один товар меньше. Проблема в том, что когда я удаляю НЕ последний элемент из списка, сбрасывается состояние элемента под ним
Сердечко будет светиться красным , если данный товар находится в массиве избранного, это отдельный кастомный виджет, который параметром принимает массив избранного и сам товар, и в initState проверяет содержится ли товар в массиве, если true то светится красным, если false то светится черным
Ответы (1 шт):
Есть предположение, что работает особенность флаттера - как можно меньше заниматься перерисовкой.
Судя по описанию, сердечко - это stateful виджет. Он имеет свой стейт и в нем есть некий указатель на продукт (допустим id). удаляется не последний продукт. картинка, текст и кнопки пересоздаются и билдятся, а вот сердечку находится соответствующий не удаленный элемент из дерева элементов. Виджет пересоздается, но стейт не отрабатывает initState, а переиспользует существующий стейт, где initState уже был вызван. Да-да, для другого продукта. Только что удаленного.
Но продукта больше нет в списке избранных, поэтому когда срабатывает метод build - сердечко не загорается.
Лечится это двумя способами:
- Передавать ключ в виджет сердечка: например, ValueKey(id). Таким образом виджет будет перестроен, когда его позиция в списке поменяется.
- Сделать виджет StateLess и вычислять значение при перестройке всей ячейки - сходить в список избранных не внутри виджета сердечка, а на уровень выше (что как бы логичнее, имхо).