使用 BottomNavigationBar 在屏幕之间切换时,Flutter 中出现“'!_needsLayout': is not true”错误

时间:2021-07-20 15:57:36

标签: flutter flutter-layout flutter-bottomnavigation

我有一个 ScaffoldBottomNavigationBar

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  int _currentIndex = 0;
  final List<Widget> _children = [
    const FirstPage(),
    const SecondPage(),
    const ThirdPage(),
  ];

  void onTabTapped(int index) {
  setState(() {
    _currentIndex = index;
  });
}

  @override
  Widget build(BuildContext context) {

    size = MediaQuery.of(context).size;
    topPadding = MediaQuery.of(context).padding.top;


    return Scaffold(
      body: _children[_currentIndex],
      bottomNavigationBar: SizedBox(
        height: 60,
        child: BottomNavigationBar(
          elevation: 0,
          selectedItemColor: Colors.orange,
          unselectedItemColor: Colors.black,
          showSelectedLabels: false,
          showUnselectedLabels: false,
          onTap: onTabTapped,
          currentIndex: _currentIndex, // this will be set when a new tab is tapped
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.video_call_rounded),
              label: "Settings",
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            )
          ],
        ),
      ),
    );
  }
}

但是当我使用 BottomNavigationBar 在屏幕之间切换时,我有时会收到错误 Unhandled Exception: 'package:flutter/src/painting/text_painter.dart': Failed assertion: line 881 pos 12: '!_needsLayout': is not true.

如何解决这个问题?

编辑

这是带有错误日志的完整代码:

ma​​in.dart

import 'package:cook_it/home.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {

    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter App!',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        splashFactory: InkRipple.splashFactory,
      ),
      home: Home(),
    );
  }
}

home.dart

import 'package:cook_it/screens/profile_page.dart';
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  int _currentIndex = 0;
  final List<Widget> _children = [
    const ProfilePage(),
    const ProfilePage(),
    const ProfilePage(),
  ];

  void onTabTapped(int index) {
  setState(() {
    _currentIndex = index;
  });
}

  @override
  Widget build(BuildContext context) {


    return Scaffold(
      body: _children[_currentIndex],
      bottomNavigationBar: SizedBox(
        height: 60,
        child: BottomNavigationBar(
          elevation: 0,
          selectedItemColor: Colors.orange,
          unselectedItemColor: Colors.black,
          showSelectedLabels: false,
          showUnselectedLabels: false,
          onTap: onTabTapped,
          currentIndex: _currentIndex, // this will be set when a new tab is tapped
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.video_call_rounded),
              label: "Settings",
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            )
          ],
        ),
      ),
    );
  }
}

profile_page.dart

import 'package:flutter/material.dart';

class ProfilePage extends StatefulWidget {
  const ProfilePage({ Key? key }) : super(key: key);

  @override
  _ProfilePageState createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: Colors.red,),
    );
  }
}

错误

E/flutter (15525): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: 'package:flutter/src/painting/text_painter.dart': Failed assertion: line 881 pos 12: '!_needsLayout': is not true.
E/flutter (15525): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter (15525): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter (15525): #2      TextPainter.getPositionForOffset
package:flutter/…/painting/text_painter.dart:881
E/flutter (15525): #3      RenderParagraph.hitTestChildren
package:flutter/…/rendering/paragraph.dart:456
E/flutter (15525): #4      RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #5      RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #6      RenderTransform.hitTestChildren.<anonymous closure>
package:flutter/…/rendering/proxy_box.dart:2347
E/flutter (15525): #7      BoxHitTestResult.addWithRawTransform
package:flutter/…/rendering/box.dart:826
E/flutter (15525): #8      BoxHitTestResult.addWithPaintTransform
package:flutter/…/rendering/box.dart:751
E/flutter (15525): #9      RenderTransform.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:2343
E/flutter (15525): #10     RenderTransform.hitTest
package:flutter/…/rendering/proxy_box.dart:2337
E/flutter (15525): #11     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #12     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #13     RenderShiftedBox.hitTestChildren.<anonymous closure>
package:flutter/…/rendering/shifted_box.dart:92
E/flutter (15525): #14     BoxHitTestResult.addWithPaintOffset
package:flutter/…/rendering/box.dart:787
E/flutter (15525): #15     RenderShiftedBox.hitTestChildren
package:flutter/…/rendering/shifted_box.dart:87
E/flutter (15525): #16     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #17     RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure>
package:flutter/…/rendering/box.dart:2775
E/flutter (15525): #18     BoxHitTestResult.addWithPaintOffset
package:flutter/…/rendering/box.dart:787
E/flutter (15525): #19     RenderBoxContainerDefaultsMixin.defaultHitTestChildren
package:flutter/…/rendering/box.dart:2770
E/flutter (15525): #20     RenderFlex.hitTestChildren
package:flutter/…/rendering/flex.dart:1072
E/flutter (15525): #21     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #22     RenderShiftedBox.hitTestChildren.<anonymous closure>
package:flutter/…/rendering/shifted_box.dart:92
E/flutter (15525): #23     BoxHitTestResult.addWithPaintOffset
package:flutter/…/rendering/box.dart:787
E/flutter (15525): #24     RenderShiftedBox.hitTestChildren
package:flutter/…/rendering/shifted_box.dart:87
E/flutter (15525): #25     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #26     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #27     RenderProxyBoxWithHitTestBehavior.hitTest
package:flutter/…/rendering/proxy_box.dart:178
E/flutter (15525): #28     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #29     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #30     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #31     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #32     RenderMouseRegion.hitTest
package:flutter/…/rendering/proxy_box.dart:2905
E/flutter (15525): #33     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #34     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #35     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #36     RenderBox.hitTest
package:flutter/…/rendering/box.dart:2414
E/flutter (15525): #37     RenderProxyBoxMixin.hitTestChildren
package:flutter/…/rendering/proxy_box.dart:131
E/flutter (15525): #38     RenderProxyBoxWithHitTestBehavior.hitTest
package:flutter/…/rendering/proxy_box.dart:178
E/flutter (15525): #39     RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure>
package:flutter/…/rendering/box.dart:2775
E/flutter (15525): #40     BoxHitTestResult.addWithPaintOffset
package:flutter/…/rendering/box.dart:787
E/flutter (15525): #41     RenderBoxContainerDefaultsMixin
E/flutter (15525): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: 'package:flutter/src/painting/text_painter.dart': Failed assertion: line 881 pos 12: '!_needsLayout': is not true.
E/flutter (15525): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter (15525): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter (15525): #2      TextPainter.getPositionForOffset
package:flutter/…/painting/text_painter.dart:881
E/flutter (15525): #3      RenderParagraph.hitTestChildren
package:flutter/…/rendering/paragraph.dart:456

我稍微修改了代码以使其更清晰,但我测试了这段代码,有时它仍然会出现相同的错误(日志在上面)。

1 个答案:

答案 0 :(得分:1)

这里有效,这里试试

import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
  const FirstPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text("1stPage"),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text("2nd Page"),
    );
  }
}

class ThirdPage extends StatelessWidget {
  const ThirdPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text("3rd PAge"),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int _currentIndex = 0;
  final List<Widget> _children = [
    const FirstPage(),
    const SecondPage(),
    const ThirdPage(),
  ];

  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    // size = MediaQuery.of(context).size;
    // topPadding = MediaQuery.of(context).padding.top;

    return Scaffold(
      body: _children[_currentIndex],
      bottomNavigationBar: SizedBox(
        height: 60,
        child: BottomNavigationBar(
          elevation: 0,
          selectedItemColor: Colors.orange,
          unselectedItemColor: Colors.black,
          showSelectedLabels: false,
          showUnselectedLabels: false,
          onTap: onTabTapped,
          currentIndex:
              _currentIndex, // this will be set when a new tab is tapped
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.video_call_rounded),
              label: "Settings",
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            )
          ],
        ),
      ),
    );
  }
}