#dart #flutter
#dart #трепетание
Вопрос:
Я получаю следующую ошибку при первой загрузке панели вкладок из моего приложения Flutter:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building TabBar(dependencies: [_InheritedTheme,
flutter: _LocalizationsScope-[GlobalKey#c29e1], _TabControllerScope], state: _TabBarState#dd10a):
flutter: The getter 'length' was called on null.
flutter: Receiver: null
flutter: Tried calling: length
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
flutter: #1 _IndicatorPainter._tabOffsetsEqual
package:flutter/…/material/tabs.dart:414
flutter: #2 _IndicatorPainter.shouldRepaint
package:flutter/…/material/tabs.dart:427
flutter: #3 RenderCustomPaint._didUpdatePainter
package:flutter/…/rendering/custom_paint.dart:433
flutter: #4 RenderCustomPaint.painter=
package:flutter/…/rendering/custom_paint.dart:398
flutter: #5 CustomPaint.updateRenderObject
package:flutter/…/widgets/basic.dart:481
flutter: #6 RenderObjectElement.update
package:flutter/…/widgets/framework.dart:4510
flutter: #7 SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:4881
(...)
Он отображается пользователю и длится всего несколько секунд, а затем все возвращается в нормальное состояние, и контроллер вкладок работает должным образом. Я попытался создать свой собственный TabController, и я все еще получаю ту же ошибку
Мой код:
class HomeScreen extends StatelessWidget {
HomeScreen();
@override
Widget build(BuildContext context) {
return SafeArea(
child: DefaultTabController(
length: 5,
initialIndex: 0,
child: Scaffold(
backgroundColor: Color(0xFF25272b),
appBar: TabBar(
tabs: [
Tab(icon: Icon(Icons.home)),
Tab(icon: Icon(Icons.settings)),
Tab(icon: Icon(Icons.media)),
Tab(icon: Icon(Icons.account_box)),
Tab(icon: Icon(Icons.notifications)),
],
),
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: [
Content1(),
Content2(),
Content3(),
Content4(),
Content5(),
],
),
),
),
);
}
}
Я попытался прокомментировать содержимое панели вкладок и TabBarView. Так что я не думаю, что это ошибка, вызванная каким-то пользовательским виджетом, который я создал.
Есть идеи о том, как это решить?
РЕДАКТИРОВАТЬ: я использую Redux. Я не знаю, может ли это повлиять на проблему. Вот мой main.dart:
class MainAppState extends State<MainApp> {
Persistor<AppState> persistor;
Store<AppState> store;
void initState() {
super.initState();
persistor = Persistor<AppState>(
storage: FlutterStorage(),
serializer: JsonSerializer<AppState>(AppState.fromJson),
);
store = Store<AppState>(
appReducer,
initialState: AppState(),
middleware : createStoreMiddleware(
widget.navigatorKey,
)
..add(persistor.createMiddleware()),
);
persistor.load()
.whenComplete(() => store.dispatch(InitAuth()) );
}
@override
Widget build(BuildContext context) {
return StoreProvider(
store: store,
child: MaterialApp(
locale: Locale('en'),
debugShowCheckedModeBanner: false,
title: 'app',
theme: AppTheme.theme,
navigatorKey: widget.navigatorKey,
initialRoute: store.state.user == null
? LoginScreen.route
: HomeScreen.route,
routes: <String, WidgetBuilder> {
HomeScreen.route : (context) {
return StoreBuilder<AppState>(
builder: (context, store) {
return HomeScreen();
},
);
},
Ответ №1:
Хорошо… Я обнаружил проблему. Это связано с тем, как Flutter повторно использует виджеты без пользовательских ключей.
Я неправильно изменил маршрут между домашним экраном и LoginScreen:
У меня была эта функция для обновления страницы:
navigatorKey.currentState.pushNamedAndRemoveUntil(action.name, ModalRoute.withName('/'));
Я изменил на:
navigatorKey.currentState.pushNamedAndRemoveUntil(action.name, (_) => false);
Итак, вероятно, приложение сохраняло некоторые ненужные данные с рабочего стола, пока не восстановит новый виджет с идеальным состоянием.
Ответ №2:
Вы проверили содержимое, ваш код отлично работает без части содержимого в TabBarView
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: [
Content1(), <--------------
Content2(), <--------------
Content3(), <--------------
Content4(), <--------------
Content5(), <--------------
],
),
),
заменено на
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: [
Text("1"),
Text("2"),
Text("3"),
Text("4"),
Text("5"),
],
),
),
работает без ошибок.
Комментарии:
1. и вызывает ли это ту же ошибку при изменении содержимого
2. Да. Точно то же самое. Ошибка длится несколько секунд (например, 3 секунды) и исчезает. Но это показано пользователю.