最近一直在学习flutter,用TarBar的时候发现的问题,不知道这是不是google的bug,如果有更好的办法请告知,相互学习,谢谢。
搞了好久就是报这个错:
The following RangeError was thrown building TabBar(dirty, state: _TabBarState#27cf7):
RangeError (index): Invalid value: Only valid value is 0: 1
本来打算自己写一个TabBar的,结果去看源码去了,相对照他的写。看源码的过程中就发现,报错的地方就是这鬼玩意:
final List<Widget> wrappedTabs = List<Widget>(widget.tabs.length);
for (int i = 0; i < widget.tabs.length; i += 1) {
wrappedTabs[i] = Center(
heightFactor: 1.0,
child: Padding(
padding: widget.labelPadding ?? kTabLabelPadding,
child: KeyedSubtree(
key: _tabKeys[i],
child: widget.tabs[i],
),
),
);
这个_tabKeys一直报角标越界的问题,fuck,找到你是个什么鬼,怎么初始化的,发现它是缓存tab宽度用的,如下代码:
@override
void initState() {
super.initState();
// If indicatorSize is TabIndicatorSize.label, _tabKeys[i] is used to find
// the width of tab widget i. See _IndicatorPainter.indicatorRect().
_tabKeys = widget.tabs.map((Widget tab) => GlobalKey()).toList();
}
在这里根据tabs的长度初始化的。然后当你拿到tab数据时,就会更新因此就会调用如下代码:
@override
void didUpdateWidget(TabBar oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.controller != oldWidget.controller) {
_updateTabController();
_initIndicatorPainter();
} else if (widget.indicatorColor != oldWidget.indicatorColor ||
widget.indicatorWeight != oldWidget.indicatorWeight ||
widget.indicatorSize != oldWidget.indicatorSize ||
widget.indicator != oldWidget.indicator) {
_initIndicatorPainter();
}
if (widget.tabs.length > oldWidget.tabs.length) {
final int delta = widget.tabs.length - oldWidget.tabs.length;
_tabKeys.addAll(List<GlobalKey>.generate(delta, (int n) => GlobalKey()));
} else if (widget.tabs.length < oldWidget.tabs.length) {
_tabKeys.removeRange(widget.tabs.length, oldWidget.tabs.length);
}
}
看到没就是在那个判断的地方不知道是啥原因,更新的时候一直是相等的这个判短if (widget.tabs.length > oldWidget.tabs.length),刚好他这没有那个判断。于是乎,妈的把它整个TabBar代码这个复制出来,再改了。如下:
if (widget.tabs.length > oldWidget.tabs.length) {
final int delta = widget.tabs.length - oldWidget.tabs.length;
_tabKeys.addAll(List<GlobalKey>.generate(delta, (int n) => GlobalKey()));
} else if (widget.tabs.length < oldWidget.tabs.length) {
_tabKeys.removeRange(widget.tabs.length, oldWidget.tabs.length);
} else {
_tabKeys.clear();
final int delta = widget.tabs.length;
_tabKeys.addAll(List<GlobalKey>.generate(delta, (int n) => GlobalKey()));
}
这时候t你以为就可以了,没错tab是显示了,但是他么的滑动的时候tab没反应,点击他么还报错,fuck!!!!又他么看源码发现如下代码:
草居然是final,我他么改不了啊。于是我就暴力点更新的时候这样搞一下:
mController = TabController(
length: tabList.length,
vsync: this,
);
我他么重新创建一个看你行不行。一试果然好了,心累啊!!!!,如果有大神知道怎么搞,有更好的方法,方便告知一下小弟一下不胜感激