#flutter #dart
#флаттер #dart
Вопрос:
У меня есть StatelessWidget
во flutter ScrollController
, у которого есть дочерний компонент этого компонента, который я StatefulWidget
добавляю scrollController.addListener
в его initState
class MyStatelessWidget extends StatelessWidget {
final ScrollController scrollController = ScrollController();
@override
Widget build(BuildContext context) {
return Column(
children: [
Placeholder(), //Complex child
Placeholder(), //Complex child
Placeholder(), //
MyStatefulWidget(
scrollController: scrollController,
) // Complex child
],
);
}
}
class MyStatefulWidget extends StatefulWidget {
final ScrollController scrollController;
const MyStatefulWidget({
@required this.scrollController,
});
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return Container();
}
@override
void initState() {
print('Scroll listener added');
widget.scrollController.addListener(() {
print('Scroll position changed');
});
super.initState();
}
}
Моя проблема в том, что при build
выполнении родительского MyStatelessWidget
элемента иногда я терял прослушиватель прокрутки
Почему? и как я могу это исправить?
Ответ №1:
_myStatefulWidget
вызывает build
, но нет initState
. Следовательно, вы не регистрируете прослушиватель на новом контроллере.
Решением было бы использовать решение для управления состоянием, чтобы разделить контроллер между виджетами. Проверьте пакет поставщика.
Комментарии:
1. это происходит и в производственном приложении
2. Решение по-прежнему заключается в использовании решения для управления состоянием. Я рекомендую вам начать с Provider, если управление состоянием для вас ново. Хотя есть и другие варианты, такие как bloc или redux.
3. Я уверен, что
addListener
это вызвано, но проблема вfinal ScrollController scrollController = ScrollController();
повторно создается4. Правильно. Я говорю, что
addListener
это не вызывается для нового объекта после повторного создания экземпляра. Виджет без состояния создается только один раз, поэтому, когда он «перестраивается», он фактически создается заново, поэтому с ним происходит то жеscrollController
самое. Однако виджет с отслеживанием состояния может быть перестроен без повторного создания экземпляра. Следовательно,initState
не вызывается, и, следовательно, слушатель не добавляется к новомуscrollController
.5. Быстрое решение — создать
_myStatelessWidget
виджет с отслеживанием состояния. Тогда он может перестроиться без повторного создания экземпляраscrollController
, но это не поможет вам понять нюансы Stateful vs. Виджеты без состояния.