Flutter: направление тела на Scaffold к нужному виджету через BottomNavigationBar

Я пытаюсь изменить значение тела Scaffoldи измените цвет BottomNavigationBarItem, чтобы отразить текущий выбранный индекс, но у меня возникли некоторые трудности. Я могу выделить выбранный индекс BottomNavigationBar() после того, как он выбран, но тело не направляется к соответствующему виджету.

Текущий метод, указанный в элементе, правильно выделяет выбранный индекс, но не выполняет маршрутизацию к нужному виджету.

Есть неиспользованный метод ( _switchScreen) в моем . Вставив это как значение в onTap: для правильного перехода к правильному экрану, но тогда мне нужно перестроить для каждого представления и он недоступен за BottomNavBar на который есть ссылка в (Модель навигации).

Вот мой BottomNavBar():

      import 'package:flutter/material.dart';

import '../screens/Add_Media_Screen.dart';
import '../screens/Profile_Screen.dart';
import '../screens/Venture_Feed_Screen.dart';
   
class BottomNavBar extends StatefulWidget {
  @override
  _BottomNavBarState createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {
  int _selectedIndex = 0;

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  void _switchScreen(index) {
    switch (index) {
      case 0:
        Navigator.pushNamed(context, VentureFeedScreen.routeName);
        break;
      case 1:
        Navigator.pushNamed(context, ProfileScreen.routeName);
        break;
      case 2:
        Navigator.pushNamed(context, AddMediaScreen.routeName);
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Theme(
      data: ThemeData(
        primaryColor: Color(0xff84d1da),
        accentColor: Color(0xff62c2a2),
      ),
      child: BottomNavigationBar(
        selectedItemColor: Color(0xff84d1da),
        unselectedItemColor: Colors.grey,
        type: BottomNavigationBarType.fixed,
        items: const <BottomNavigationBarItem>[
          //Index 0
          BottomNavigationBarItem(
            icon: Icon(
              Icons.explore,
            ),
            label: 'Discover',
          ),
          //Index 1
          BottomNavigationBarItem(
            icon: Icon(
              Icons.account_circle,
              // color: Color(0xff84d1da),
            ),
            label: 'Profile',
            // backgroundColor: Color(0xff84d1da),
          ),
          //Index 2
          BottomNavigationBarItem(
            icon: Icon(
              Icons.add_circle_outline,
            ),
            label: 'Add Media',
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}

Здесь NavModel:

      import 'package:flutter/material.dart';

import '../screens/Profile_Screen.dart';
import '../screens/Venture_Feed_Screen.dart';
import '../screens/Add_Media_Screen.dart';

import '../widgets/BottomNavBar.dart';

class NavModel extends StatefulWidget {
  static const routeName = '/nav-model';
  @override
  _NavModelState createState() => _NavModelState();
}

class _NavModelState extends State<NavModel> {
  int _currentIndex = 0;

  final tabs = [
    VentureFeedScreen(),
    ProfileScreen(),
    AddMediaScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: tabs[_currentIndex],
        bottomNavigationBar: BottomNavBar(),
      ),
    );
  }
}

2 ответа

Решение

Разделение его на два разных класса в этом сценарии не сработает. в NavModel() class для свойства, я пытался обновить значение tabs список согласно _currentIndex со значением статического индекса, равным 0. Я думал, что, вызвав BottomNavBar() класс и установление onTap: значение для обновления в соответствии с методом, которым он обновил бы body: значение в соответствии с тем, что было определено в _onItemTappedметод внутри класса. Это было неправильно.

Код работал правильно, как я его определил: body: tabs[_currentIndex]Scaffold вызывал правильную логику - отображать элемент с индексом 0 в списке вкладок. В то время как это происходило, индекс BottomNavBar обновлялся, чтобы отразить правильный выбранный пользователем индекс и значения, что вызвало путаницу в том, почему выбранный индекс BottomNavBar обновлялся, в то время как тело Scaffold оставалась постоянной.

Вот правильный код:

      class BottomNavBar extends StatefulWidget {
  static const routeName = '/navigator-model';
  @override
  _BottomNavBarState createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {
  int _selectedIndex = 0;

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  final List<Widget> tabs = [
    VentureFeedScreen(),
    ProfileScreen(),
    AddMediaScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: tabs.elementAt(_selectedIndex),
      bottomNavigationBar: BottomNavigationBar(
        selectedItemColor: Color(0xff84d1da),
        unselectedItemColor: Colors.grey,
        type: BottomNavigationBarType.fixed,
        items: const <BottomNavigationBarItem>[
          //Index 0
          BottomNavigationBarItem(
            icon: Icon(
              Icons.explore,
            ),
            label: 'Discover',
          ),
          //Index 1
          BottomNavigationBarItem(
            icon: Icon(
              Icons.account_circle,
              // color: Color(0xff84d1da),
            ),
            label: 'Profile',
            // backgroundColor: Color(0xff84d1da),
          ),
          //Index 2
          BottomNavigationBarItem(
            icon: Icon(
              Icons.add_circle_outline,
            ),
            label: 'Add Media',
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}

Однако мне еще предстоит увидеть, BottomNavBar сохраняется при переходе на другой экран (эта функция еще не реализована).

Я думаю, что вы пытаетесь достичь поведения класса PageView , верно? Сделайте PageView тело вашего каркаса и передайте tabs как дочерние элементы PageView.

Другие вопросы по тегам