【问题标题】:Why FutureBuilder re-build every time?为什么 FutureBuilder 每次都重新构建?
【发布时间】:2022-07-23 00:09:27
【问题描述】:

我正在使用 FutureBuilder 并在 InitState 中初始化 _future,如 here 所述。 尽管如此,每次我使用BottomNavigationBar 切换页面时,FutureBuilder 都会重新构建自己。

代码示例:

class _HomeViewState extends State<HomeView> {

  late final Future<List<DocumentSnapshot<Object?>>> _futureSerieA;



  @override
  void initState() {

    super.initState();
    _futureSerieA = getScheduled("Serie A");

  }

  @override
  Widget build(BuildContext context) {
    return SizedBox.expand(
      child: SingleChildScrollView(
        child: Column(
          children: [


            Padding(
              padding: const EdgeInsets.fromLTRB(0,0,0,0),
              child: Container(
                decoration: const BoxDecoration(

                  border: Border(

                    bottom: BorderSide(color: Colors.transparent)
                  )
                ),
                child: Theme(
                  data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
                  child: FutureBuilder(
                    future: _futureSerieA,
                    builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {

                      if (snapshot.hasData) {
                        List<String> scheduled = [];

                        for (var DOC in snapshot.data!) {
                          scheduled.add(DOC.id);
                        }
                        return ...

在BottomNavigationBar的页面之间浏览时如何禁用FutureBuilder重新构建?

底部导航栏:

class _LoggedHandleState extends State<LoggedHandle> {

 
  );
  double height = AppBar().preferredSize.height;

  int _selectedPage = 1;
  final _pageOptions = [
    const BetView(),
    const HomeView(),
    const UserView()
  ];




  @override
  Widget build(BuildContext context) {
    return Scaffold(

      ...
      ),
    

      bottomNavigationBar: BottomNavigationBar(
          unselectedItemColor: Colors.white60,
          backgroundColor: Colors.red,
          selectedItemColor: Colors.white,
          currentIndex: _selectedPage,
          onTap: (int index) {
            setState(() {
              _selectedPage = index;
            });
          },
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.receipt),
              label: 'Schedina',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.account_circle),
              label: 'Account',
            ),
          ]),

      body: _pageOptions[_selectedPage],
    );
  }

 
}

【问题讨论】:

  • 我更喜欢在StatefulWidget上使用可空数据
  • 这会影响FutureBuilder 的行为吗?
  • 你能提供一个简化的小部件来重现同样的错误
  • 很复杂,未来getScheduled与FirebaseAuth和Firestore一起工作...我可以附上BottomNavigationBar的代码,我认为问题是每次更改时都会调用InitState页面
  • 你可以创建一个虚拟的未来来重现错误

标签: flutter dart flutter-futurebuilder


【解决方案1】:

在底部导航栏的页面之间浏览时,您的状态不会保持。这种行为会导致小部件每次都重新构建。

您可以使用索引堆栈https://api.flutter.dev/flutter/widgets/IndexedStack-class.html

  @override
      Widget build(BuildContext context) {
        return Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            onTap: (index) {
              setState(() {
                current_tab = index;
              });
            },
            currentIndex: current_tab,
            items: [
              BottomNavigationBarItem(
                ...
              ),
              BottomNavigationBarItem(
                ...
              ),
            ],
          ),
          body: IndexedStack(
            children: <Widget>[
              PageOne(),
              PageTwo(),
            ],
            index: current_tab,
          ),
        );
      }

虽然这是最好的解决方案,但它会在加载 IndexedStack 后加载所有小部件。 我发现了一个延迟加载索引堆栈实用程序,用于在并且仅在第一次创建小部件时加载您的小部件https://github.com/okaryo/lazy_load_indexed_stack

【讨论】:

  • 谢谢,我要测试这个解决方案。只是我不太明白你回答的最后一部分:我为什么需要lazy_load_indexed_stack?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多