【Flutter】解決BottomNavigationBar動(dòng)態(tài)更新RangeError問(wèn)題

今天在做一個(gè)需求,動(dòng)態(tài)更新底部導(dǎo)航菜單BottomNavigationBar。本來(lái)很簡(jiǎn)單的一個(gè)需求卻踩了一個(gè)坑,特此記錄一下。

問(wèn)題:

在更新菜單item數(shù)據(jù)后,通過(guò)setState((){})刷新 BottomNavigationBar

  _buildNavigationBar() {
    return BottomNavigationBar(
      type: BottomNavigationBarType.fixed,
      unselectedFontSize: 10,
      selectedFontSize: 10,
      backgroundColor: Colors.white,
      items: barItemList,
      currentIndex: _index,
      onTap: (value) async {
      },
    );
  }

這時(shí)候直接報(bào)錯(cuò):

RangeError (index): Invalid value: Not in inclusive range 0..1: 2

字面意思是index越界了。
但通過(guò)打印確認(rèn)了index的值并沒(méi)有越界,那是哪里不對(duì)?

原因:

分析BottomNavigationBar源碼后發(fā)現(xiàn)只有在它的initState()才會(huì)去更新數(shù)據(jù),

  @override
  void didUpdateWidget(BottomNavigationBar oldWidget) {
    super.didUpdateWidget(oldWidget);

    // No animated segue if the length of the items list changes.
    if (widget.items.length != oldWidget.items.length) {
      _resetState();
      return;
    }
    ……

但setState((){})并沒(méi)有重新執(zhí)行initState(),只是重新build(),所以BottomNavigationBar拿到的items長(zhǎng)度還是舊的數(shù)據(jù)。

解決:

確定了原因解決方法就比較清晰了,就是需要讓BottomNavigationBar重新創(chuàng)建,執(zhí)行它的didUpdateWidget(),方法是我們可以改變它的key來(lái)觸發(fā)。
首先給它設(shè)置一個(gè)key:

  var _navBarKey = UniqueKey();

  _buildNavigationBar() {
    return BottomNavigationBar(
      key: _navBarKey,
      type: BottomNavigationBarType.fixed,
      unselectedFontSize: 10,
      selectedFontSize: 10,
      backgroundColor: Colors.white,
      items: barItemList,
      currentIndex: _index,
      onTap: (value) async {
      },
    );
  }

在更新完數(shù)據(jù),只需要修改它的key就可以:

//  更新數(shù)據(jù)完成,刷新UI:
_navBarKey = UniqueKey();

以此類推,要讓其他Widget重新創(chuàng)建也可以用同樣的方法。

最后,補(bǔ)充說(shuō)明一下UniqueKey():

UniqueKey是Flutter框架中的一個(gè)特殊類型,用于為Widget對(duì)象生成唯一的標(biāo)識(shí)符。它是Key類的子類,用于標(biāo)識(shí)Widget樹中的一個(gè)節(jié)點(diǎn),并確保它是唯一的。

End

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 0、Dart是值傳遞還是引用傳遞? Dart是值傳遞。每次調(diào)用函數(shù),傳遞過(guò)去的都是對(duì)象的內(nèi)存地址,不是對(duì)象的復(fù)制。...
    woniu閱讀 3,564評(píng)論 1 24
  • Dart 相關(guān) 1、Dart 當(dāng)中的 「..」表示什么意思? 級(jí)連操作符 “..” 和 “.” 不同:調(diào)用..后返...
    af06e7def7a7閱讀 2,568評(píng)論 0 2
  • 邂逅FLutter 萬(wàn)物皆是Widget 一般縮進(jìn)2個(gè)空格 文字居中 Widget Center() Materi...
    JackLeeVip閱讀 3,494評(píng)論 0 4
  • 本文主要以下代碼介紹flutter中element的生命周期。 1、示例 運(yùn)行結(jié)果 2、展示column樹結(jié)構(gòu) 可...
    freelifes閱讀 504評(píng)論 0 2
  • 本文介紹了Flutter應(yīng)用程序中Widget,State,Context和InheritedWidget的重要概...
    不要和哥鬧閱讀 4,046評(píng)論 1 2

友情鏈接更多精彩內(nèi)容