Динамически изменяйте тело каркаса с помощью списка виджетов

#flutter #dart #flutter-layout

Вопрос:

У меня есть список виджетов, которые должны действовать как тело в виджете «Каркас» (в Dashboard классе) в соответствии с activeIndex , BottomNavigationBar но тело не обновляется при activeIndex изменении.

Код нижней навигационной панели:

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

  int activeIndex = 1;

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

class _BottomNavBarState extends State<BottomNavBar> {
  final Color primaryColor = Color(0xff2FC4B2);
  final Color inactiveIconColor = Colors.white;
  final Color activeIconColor = Colors.blue;

  void setIndex(int index) {
    setState(() {
      widget.activeIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
            icon: Icon(
              Icons.track_changes_outlined,
              color: inactiveIconColor,
            ),
            activeIcon: Icon(
              Icons.track_changes_outlined,
              color: activeIconColor,
            ),
            label: "Track"),
        BottomNavigationBarItem(
            icon: Icon(
              Icons.home_outlined,
              color: inactiveIconColor,
            ),
            activeIcon: Icon(
              Icons.home_outlined,
              color: activeIconColor,
            ),
            label: "Home"),
        BottomNavigationBarItem(
            icon: Icon(
              Icons.settings_outlined,
              color: inactiveIconColor,
            ),
            activeIcon: Icon(
              Icons.settings_outlined,
              color: activeIconColor,
            ),
            label: "Settings")
      ],
      backgroundColor: primaryColor,
      fixedColor: Colors.white,
      showSelectedLabels: false,
      showUnselectedLabels: false,
      currentIndex: widget.activeIndex,
      onTap: setIndex,
    );
  }
}
 

Код Панели мониторинга:

 class Dashboard extends StatefulWidget {
  final String? userID;
  final String? userName;

  Dashboard(this.userID, this.userName);

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

class _DashboardState extends State<Dashboard> {
  BottomNavBar navBar = new BottomNavBar();

  @override
  Widget build(BuildContext context) {
    List<Widget> navBarItems = [Track(), Home(widget.userID, widget.userName)];
    return Scaffold(
      bottomNavigationBar: navBar,
      body: navBarItems.elementAt(navBar.activeIndex),
    );
  }
}
 

Ответ №1:

Работа с состоянием индекса бара должна быть такой:

 class BottomNavBar extends StatefulWidget {

BottomNavBar({Key? key, int initialIndex = 1, required Function onIndexChanged}) : super(key: key);
    
final int initialIndex;
final Function(int) onIndexChanged;
    
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
    
class _BottomNavBarState extends State<BottomNavBar> {
    
  late int activeIndex;
    
  @override
  void initState() {
    super.initState();
    activeIndex = widget.initialIndex;
  }
    
  void setIndex(int _index) {
    setState(() {
      activeIndex = _index;
    });
    widget.onIndexChanged(activeIndex);
  }
    
@override
Widget build(BuildContext context) {
  ///other code
  currentIndex: activeIndex,
  onTap: setIndex,
  ///other code
 }
}
 

 class _DashboardState extends State<Dashboard> {

  int currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    List<Widget> navBarItems = [Track(), Home(widget.userID, 
    widget.userName)];
    return Scaffold(
      bottomNavigationBar: BottomNavBar(
        initialIndex: 1,
        onIndexChanged: (int index) {
           setState(() {
             currentIndex = index;
           });
        }
      ),
      body: navBarItems.elementAt(currentIndex),
    );
  }
 

Документация StatefulWidget

Комментарии:

1. Как мне получить доступ к текущему индексу панели навигации в классе панели мониторинга здесь, поскольку activeIndex находится в частном классе?

2. @Tartarus Вы можете использовать функцию обратного вызова. Я обновил ответ. Надеюсь, это поможет

3. Я получаю сообщение об ошибке «setState() или markNeedsBuild (), вызванное во время сборки».

4. @Tartarus Я обновил код. Посмотрите на метод initState в _BottomNavBarState