轉載請標明出處: juejin.im/post/5b7e25…
本文出自:Wos的主頁
如果發生 '_debugUltimatePreviousSiblingOf(after, equals: _firstChild)': is not true.
的錯誤, 請檢查是否是以下原因造成的, 並根據下文進行修改
注意: 這篇文章版本久遠, 可能不再適用於新版本. 僅供參考, 慎用
示例:
class _HomeContainerState extends State<HomeContainer> {
PageController _pageController;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_pageController = new PageController();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: PageView(
children: <Widget>[
new Container(
child: new Page1(),
),
new Container(
child: new Page2(),
),
new Container(
child: new Page3(),
),
Container(
child: new Page4(),
),
],
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
onPageChanged: (int index){
setState(() {
_currentIndex = index;
});
},
),
bottomNavigationBar: BottomNavigationBar(
items: [
_buildItem('page1'),
_buildItem('page2'),
_buildItem('page3'),
_buildItem('page4'),
],
onTap: (int index) {
_pageController.jumpToPage(index);
},
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
),
);
}
_buildItem(String title){
return BottomNavigationBarItem(
icon: Icon(
Icons.account_balance,
),
title: Text(title),
);
}
}
複製程式碼
以上程式碼會造成崩潰, 報錯資訊如下:
報錯資訊:
Restarted app in 2,823ms.
I/flutter (24543): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (24543): The following assertion was thrown building NotificationListener<KeepAliveNotification>:
I/flutter (24543): 'package:flutter/src/rendering/object.dart': Failed assertion: line 2775 pos 14:
I/flutter (24543): '_debugUltimatePreviousSiblingOf(after, equals: _firstChild)': is not true.
I/flutter (24543): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (24543): more information in this error message to help you determine and fix the underlying cause.
I/flutter (24543): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (24543): https://github.com/flutter/flutter/issues/new
I/flutter (24543): When the exception was thrown, this was the stack:
I/flutter (24543): #2 _RenderSliverMultiBoxAdaptor&RenderSliver&ContainerRenderObjectMixin._insertIntoChildList (package:flutter/src/rendering/object.dart)
I/flutter (24543): #3 _RenderSliverMultiBoxAdaptor&RenderSliver&ContainerRenderObjectMixin.insert (package:flutter/src/rendering/object.dart:2809:5)
I/flutter (24543): #4 RenderSliverMultiBoxAdaptor.insert (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:209:11)
I/flutter (24543): #5 SliverMultiBoxAdaptorElement.insertChildRenderObject (package:flutter/src/widgets/sliver.dart:865:18)
I/flutter (24543): #6 RenderObjectElement.attachRenderObject (package:flutter/src/widgets/framework.dart:4513:35)
I/flutter (24543): #7 RenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4279:5)
I/flutter (24543): #8 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4653:11)
I/flutter (24543): #9 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
I/flutter (24543): #10 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
I/flutter (24543): #11 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #12 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #13 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5)
I/flutter (24543): #14 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5)
I/flutter (24543): #15 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
I/flutter (24543): #16 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
I/flutter (24543): #17 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #18 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #19 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5)
I/flutter (24543): #20 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5)
I/flutter (24543): #21 ParentDataElement.mount (package:flutter/src/widgets/framework.dart:3955:11)
I/flutter (24543): #22 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
I/flutter (24543): #23 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
I/flutter (24543): #24 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #25 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #26 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5)
I/flutter (24543): #27 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3769:11)
I/flutter (24543): #28 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5)
I/flutter (24543): #29 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
I/flutter (24543): #30 Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
I/flutter (24543): #31 SliverMultiBoxAdaptorElement.updateChild (package:flutter/src/widgets/sliver.dart:744:36)
I/flutter (24543): #32 SliverMultiBoxAdaptorElement.performRebuild (package:flutter/src/widgets/sliver.dart:702:34)
I/flutter (24543): #33 SliverMultiBoxAdaptorElement.update (package:flutter/src/widgets/sliver.dart:671:7)
I/flutter (24543): #34 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #35 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4379:32)
I/flutter (24543): #36 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4769:17)
I/flutter (24543): #37 _ViewportElement.update (package:flutter/src/widgets/viewport.dart:192:11)
I/flutter (24543): #38 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #39 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #40 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #41 ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
I/flutter (24543): #42 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #43 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #44 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #45 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #46 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #47 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #48 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #49 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #50 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #51 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #52 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #53 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #54 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #55 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #56 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #57 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #58 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #59 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #60 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #61 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #62 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #63 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #64 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #65 StatelessElement.update (package:flutter/src/widgets/framework.dart:3702:5)
I/flutter (24543): #66 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #67 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #68 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #69 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #70 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #71 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #72 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #73 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #74 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #75 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #76 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #77 StatelessElement.update (package:flutter/src/widgets/framework.dart:3702:5)
I/flutter (24543): #78 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #79 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #80 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #81 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #82 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #83 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #84 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #85 ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
I/flutter (24543): #86 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #87 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #88 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #89 ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
I/flutter (24543): #90 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #91 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4379:32)
I/flutter (24543): #92 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4769:17)
I/flutter (24543): #93 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #94 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #95 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #96 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #97 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #98 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #99 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #100 ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
I/flutter (24543): #101 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #102 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #103 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #104 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #105 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #106 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #107 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #108 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #109 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #110 StatelessElement.update (package:flutter/src/widgets/framework.dart:3702:5)
I/flutter (24543): #111 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #112 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
I/flutter (24543): #113 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #114 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #115 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #116 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #117 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #118 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #119 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #120 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #121 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #122 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #123 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #124 ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
I/flutter (24543): #125 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #126 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #127 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #128 ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
I/flutter (24543): #129 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #130 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #131 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #132 StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
I/flutter (24543): #133 Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
I/flutter (24543): #134 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
I/flutter (24543): #135 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (24543): #136 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2242:33)
I/flutter (24543): #137 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:626:20)
I/flutter (24543): #138 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5)
I/flutter (24543): #139 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter (24543): #140 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter (24543): #141 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter (24543): #142 _invoke (dart:ui/hooks.dart:120:13)
I/flutter (24543): #143 _drawFrame (dart:ui/hooks.dart:109:3)
I/flutter (24543): (elided 2 frames from class _AssertionError)
複製程式碼
下面先來介紹兩種簡單的解決方法:
解決辦法一:
將jumpToPage
替換為animateToPage
_pageController.animateToPage(
index,
duration: Duration(milliseconds: 260),
curve: Curves.fastOutSlowIn,
)
複製程式碼
簡單, 但是有動畫效果.
解決辦法二:
刪除onPageChanged
, 通過PageController.addListener
監聽頁面變化
_pageController = new PageController()
..addListener(() {
if (_currentIndex != _pageController.page.round()) {
setState(() {
_currentIndex = _pageController.page.round();
});
}
});
複製程式碼
這種方法僅在禁用PageView的滑動操作(NeverScrollableScrollPhysics
)且使用_pageController.jumpToPage
進行頁面切換時生效.
解決辦法三:
使用IndexedStack替代PageView
解決辦法四: (推薦)
-
新建一個檔案:
rebuild_layout.dart
-
將下列程式碼拷貝到該檔案
import 'package:flutter/material.dart';
class RebuildLayout extends StatefulWidget {
final WidgetBuilder builder;
final RebuildLayoutController controller;
RebuildLayout({Key key, @required this.builder, @required this.controller}) : super(key: key);
@override
_RebuildLayoutState createState() => _RebuildLayoutState();
}
class _RebuildLayoutState extends State<RebuildLayout> {
@override
void initState() {
super.initState();
widget.controller.addListener(_onRebuild);
}
@override
void didUpdateWidget(RebuildLayout oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != widget.controller) {
oldWidget.controller.removeListener(_onRebuild);
widget.controller.addListener(_onRebuild);
}
}
@override
void dispose() {
widget.controller._listeners.clear();
super.dispose();
}
_onRebuild() => setState(() {});
@override
Widget build(BuildContext context) {
return widget.builder(context);
}
}
class RebuildLayoutController extends Listenable {
List<VoidCallback> _listeners = [];
@override
void addListener(listener) {
_listeners.add(listener);
}
@override
void removeListener(listener) {
_listeners.remove(listener);
}
notification() {
for(var listener in _listeners){
listener();
}
}
}
複製程式碼
- 在
BottomNavigationBar
外面套一層RebuildLayout
bottomNavigationBar: RebuildLayout(builder: (BuildContext context){
return BottomNavigationBar(
...
onTap: (int index) {
_pageController.jumpToPage(index);
},
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
);
}, controller: _rebuildLayoutController),
複製程式碼
- 在
initState()
宣告週期中建立_rebuildLayoutController
RebuildLayoutController _rebuildLayoutController;
@override
void initState() {
super.initState();
...
_rebuildLayoutController = RebuildLayoutController();
}
複製程式碼
- 在
PageView
的onPageChanged
屬性中呼叫rebuildLayoutController.notification()
body: PageView(
...
onPageChanged: (int index){
_currentIndex = index;
rebuildLayoutController.notification();
},
),
複製程式碼
RebuildLayout的思路是: 只通知其子控制元件重建, 而不影響其它控制元件.
沒使用RebuildLayout之前, onPageChanged
回撥中會呼叫setState
來重新整理頁面, 這將導致PageView和BottomNavigationBar都被重建, 造成效能損耗.
這個控制元件幾乎是完全解耦的, 因此可以用在很多隻想區域性重新整理的地方.
以上, 希望能夠解決你的問題 :)