保持每个屏幕底部的导航栏颤动

时间:2020-06-23 05:11:17

标签: flutter dart flutter-layout

我有一个带有中心停靠浮动图标的底部导航栏,该底部栏存在,并且我可以浏览底部栏中的选项卡元素,但是我需要显示固定在每个屏幕上的底部栏,无论我打开的屏幕是什么显示底部导航栏

1。如果我要转到主屏幕,并且要单击首页中的某个项目并重定向到下一页,那么该如何在子页面示例中查看底部栏?底部导航栏应显示已重定向的页面

底部导航

class BottomViewScreenState extends State<BottomViewScreen> {
  TabController tabController;

 static int _selectedTab = 0;
  final List<Widget> _children = [
    new HomeScreen(),
    new OfferScreen(),
    new HelpScreen(),
    new ProfileScreen(),
    new CartViewScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Color(0xffFF5555),
      ),
      home: Scaffold(
        body: _children[_selectedTab], // new
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            // new CartViewScreen();
            //onTabTapped(4);
            // CartViewScreen();
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => CartViewScreen(),
              ),
            );
          },
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Icon(Icons.add_shopping_cart),
              Text(
                "CART",
                style: TextStyle(fontSize: 8.0),
              ),
            ],
          ),
          backgroundColor: Colors.indigo[900],
          foregroundColor: Colors.white,
          elevation: 2.0,
        ),
        bottomNavigationBar: BottomAppBar(
          clipBehavior: Clip.antiAlias,
          notchMargin: 10.0,
          shape: CircularNotchedRectangle(),
          child: SizedBox(
            height: 80,
            child: Theme(
              data: Theme.of(context).copyWith(
                  // sets the background color of the `BottomNavigationBar`
                  canvasColor: Colors.white,

                  // sets the active color of the `BottomNavigationBar` if `Brightness` is light
                  primaryColor: Colors.amberAccent,
                  textTheme: Theme.of(context)
                      .textTheme
                      .copyWith(caption: new TextStyle(color: Colors.grey))),
              child: BottomNavigationBar(
                type: BottomNavigationBarType.fixed,
                onTap: onTabTapped,
                currentIndex: _selectedTab,
                fixedColor: Colors.amberAccent,
                items: [
                  BottomNavigationBarItem(
                    icon: Icon(Icons.home),
                    title: Text(
                      'HOME',
                      style: TextStyle(fontSize: 10.0),
                    ),
                    activeIcon: Column(
                      children: <Widget>[
                        Icon(Icons.local_offer),
                      ],
                    ),
                  ),
                  BottomNavigationBarItem(
                      icon: SvgPicture.asset(
                        "assets/images/ic_bottom_offer.svg",
                        height: 25,
                        color: Colors.grey,
                      ),
                      title: Text('OFFERS', style: TextStyle(fontSize: 10.0))),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.info_outline),
                      title: Text('HELP', style: TextStyle(fontSize: 10.0))),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.people),
                      title: Text('PROFILE', style: TextStyle(fontSize: 10.0))),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

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

主要

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "App",
      home: new SplashScreen(),
      routes: {
        "/homescreen": (_) => new BottomViewScreen(),
        "/login":(_) => new LoginScreen(),
       
      },
    );
  }
}

4 个答案:

答案 0 :(得分:1)

我已经通过使用此插件Presistant_bottom_nav_bar解决了这个问题。现在我可以在每个屏幕上使用bottomnavbar

PersistentTabController _controller =PersistentTabController(initialIndex: 0);

//Screens for each nav items.
  List<Widget> _NavScreens() {
    return [
     HomeScreen(),
     OfferScreen(),
     HelpScreen(),
     ProfileScreen(),
     CartViewScreen(),
      
    ];
  }


  List<PersistentBottomNavBarItem> _navBarsItems() {
    return [
      PersistentBottomNavBarItem(
       icon: Icon(Icons.home),
        title: ("Home"),
        activeColor: CupertinoColors.activeBlue,
        inactiveColor: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.favorite),
        title: ("OFFERS"),
        activeColor: CupertinoColors.activeGreen,
        inactiveColor: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.person_pin),
        title: ("Help"),
        activeColor: CupertinoColors.systemRed,
        inactiveColor: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.local_activity),
        title: ("ProfileScreen"),
        activeColor: CupertinoColors.systemIndigo,
        inactiveColor: CupertinoColors.systemGrey,
      ),
 PersistentBottomNavBarItem(
        icon: Icon(Icons.shop_cart),
        title: ("Cart"),
        activeColor: CupertinoColors.systemIndigo,
        inactiveColor: CupertinoColors.systemGrey,
      ),

    ];
  }
@override
Widget build(BuildContext context) {
    return Center(
      child: PersistentTabView(
        controller: _controller,
        screens: _NavScreens(),
        items: _navBarsItems(),
        confineInSafeArea: true,
        backgroundColor: Colors.white,
        handleAndroidBackButtonPress: true,
        resizeToAvoidBottomInset: true,
        hideNavigationBarWhenKeyboardShows: true,
        decoration: NavBarDecoration(
          borderRadius: BorderRadius.circular(10.0),
        ),
        popAllScreensOnTapOfSelectedTab: true,
        navBarStyle: NavBarStyle.style9,
      ),
    );
}

答案 1 :(得分:0)

在我的项目中,上述情况相同: 导航栏可处理4页

List<Widget> homeTap = [
  HistoryView(),
  ScanView(),
  SearchView(),
  FavoriteView()
];

SearchView内部包含许多页面。

    class SearchView extends StatefulWidget {
  @override
  _SearchViewState createState() => _SearchViewState();
}

   

     class _SearchViewState extends State<SearchView> {
          @override
          Widget build(BuildContext context) {
            final provider = Provider.of<SearchProvider>(context, listen: false);
            return PageView(
              controller: provider.pageController,
              physics: const NeverScrollableScrollPhysics(),
              children: <Widget>[
                CategoryView(),
                CategoryDetailView(),
                buildDetailPage(),
              ],
            );
          }
       
        }

如果要导航任何页面,请使用pageController.nextPage或jumToPage

答案 2 :(得分:0)

我还建议使用 IndexedStack 作为父窗口小部件,因为它可以保存窗口小部件状态(如果您有静态页面,则无需这样做)

  int _selectedIndex = 0;

  static List<Widget> _widgetOptions = <Widget>[
    Widget1(),
    Widget2(),
    Widget3(),
  ];

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

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

      body: IndexedStack(
        index: _selectedIndex,
        children: _widgetOptions),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Widget 1'),
          ),
          BottomNavigationBarItem(
            icon: Icon(
              Icons.note),
            title: Text('Widget 2'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.message),
            title: Text('Widget 3'),
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.black,
        unselectedItemColor: Colors.grey,
        onTap: _onItemTapped,
      ),
    );
  }

答案 3 :(得分:0)

您可以通过两种方法处理这种情况-

页面浏览方法已在上面讨论,我将解释IndexedStack方法-

IndexedStack是Flutter中Stack小部件的扩展,与Stack Widget相比,它基于列表中的索引将所有子级显示在彼此之上,而Indexed小部件仅显示单个子级在儿童名单中。

IndexedStack具有两个重要属性-

  • index:这确定要从子代列表中显示的子代的索引。
  • children:所有可用孩子的列表。

以下代码显示了解决上述问题的实现-

创建一个有状态的小部件以保存所有可能的视图的列表,要显示的视图的当前索引以及底部导航栏。

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  
  int _currentIndex = 0;
  const List<Widget> _pages = <Widget>[
    HomeView(),
    OffersView(),
    HelpView(),
    ProfileView(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        top: false,
        child: IndexedStack(
          index: _currentIndex,
          children: _pages,
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
        items: [
                  BottomNavigationBarItem(
                    icon: Icon(Icons.home),
                    title: Text(
                      'HOME',
                      style: TextStyle(fontSize: 10.0),
                    ),
                    activeIcon: Column(
                      children: <Widget>[
                        Icon(Icons.local_offer),
                      ],
                    ),
                  ),
                  BottomNavigationBarItem(
                      icon: SvgPicture.asset(
                        "assets/images/ic_bottom_offer.svg",
                        height: 25,
                        color: Colors.grey,
                      ),
                      title: Text('OFFERS', style: TextStyle(fontSize: 10.0),
                    ),
                  ),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.info_outline),
                      title: Text('HELP', style: TextStyle(fontSize: 10.0),
                    ),
                  ),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.people),
                      title: Text('PROFILE', style: TextStyle(fontSize: 10.0),
                    ),
                  ),
                ],
      ),
    );
  }
}

最后运行应用程序-

void main() {
  runApp(MaterialApp(home: HomePage(), debugShowCheckedModeBanner: false));
}

我们完成了!