颤动:状态更新时BottomNavigationBar中currentIndex属性的值不会更新

时间:2020-04-15 15:21:49

标签: flutter flutter-layout flutter-navigation flutter-bottomnavigation

我有一个BottomNavigationBar,可以在按下图标时导航到其他页面。除状态更新时BottomNavigationBar中currentIndex属性的值不更新外,这表示一切正常,这意味着静态的BottomNavigationBar不变。 enter image description here

我正在使用一个可变的(_selectedPage)跟踪BottomNavigationBar中的选定索引,并且在点击一个项目时值会更改,但是当状态更新时它并没有更新currentIndex属性。为什么?< / p>

import 'package:flutter/material.dart';
import 'package:independentproject/pages/home_page.dart';
import 'package:independentproject/pages/cook_recipe.dart';

class PageNavigationBar extends StatefulWidget {
  @override
  _PageNavigationBarState createState() => _PageNavigationBarState();
}

class _PageNavigationBarState extends State<PageNavigationBar> {
  //default page showing in bottom navigation bar will be CookRecipe()
  int _selectedPage = 1;

//all pages optional in bottom navigation bar
  final List<Widget> _pageOptions = [
    HomePage(),
    CookRecipe(),
  ];

  void onTapped(int pageTapped) {
    setState(() {
      //print(pageTapped);
      _selectedPage = pageTapped;
      Navigator.push(context, MaterialPageRoute(builder: (context) => _pageOptions[pageTapped]));
      //print(_selectedPage);
    });
  }

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      //TODO: currentIndex: doesn't update when the state updates, why?
      currentIndex: _selectedPage,
        //items showing in bottom navigation bar
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          title: Text('Homepage'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.search),
          title: Text('Search recipe'),
        ),
      ],
      onTap: (int pageTapped) {
        onTapped(pageTapped);
      },
    );
  }
}

import 'package:flutter/material.dart';
import 'package:independentproject/page_navigation_bar.dart';

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

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Home page'),
        ),
        body: Center(
          child: Text('Home page'),
        ),
        bottomNavigationBar: PageNavigationBar(),
      ),
    );
  }
}

import 'package:flutter/material.dart';
import 'package:independentproject/page_navigation_bar.dart';

class CookRecipe extends StatefulWidget {
  @override
  _CookRecipeState createState() => _CookRecipeState();
}

class _CookRecipeState extends State<CookRecipe> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Search recipe'),
        ),
        body: Center(
          child: Text('Search recipes'),
        ),
        bottomNavigationBar: PageNavigationBar(),
      ),
    );
  }
}

3 个答案:

答案 0 :(得分:0)

我建议您创建一个包含BottomNavigationBarPageView的小部件,该小部件将允许您使用PageController切换页面。 例如:

class _MainScreenState extends State<MainScreen> {
  PageController _pageController;
  int _page = 1;
  Duration pageChanging = Duration(milliseconds: 300);//this is for page animation-not necessary
  Curve animationCurve = Curves.linear;//this is for page animation-not necessary
  _MainScreenState();


@override
  void initState() {
    super.initState();
    _pageController = PageController(initialPage: 1);
  }


Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        physics: BouncingScrollPhysics(),
        scrollDirection: Axis.horizontal,
        controller: _pageController,
        onPageChanged: onPageChanged,
        children: <Widget>[
          //here are all the pages you need:
          //CookRecipe(),
        ],
      ),
bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(
                Icons.message,
              ),
              title: Container(height: 0.0),
            ),
            BottomNavigationBarItem(
              icon: Icon(
                Icons.home,
              ),
              title: Container(height: 0.0),
            ),
            BottomNavigationBarItem(
              icon: Icon(
                Icons.person,
              ),
              title: Container(height: 0.0),
            ),
          ],
          onTap: navigationTapped,
          selectedItemColor: Theme.of(context).backgroundColor,
          currentIndex: _page,
        ),
      ),
    );
  }

void navigationTapped(int page) {
    _pageController.animateToPage(page,duration: pageChanging,
      curve: animationCurve,);
  }



  @override
  void dispose() {
    super.dispose();
    _pageController.dispose();
  }

  void onPageChanged(int page) {
    if (this.mounted){
    setState(() {
      this._page = page;
    });
  }}


您也可以在没有PageView的情况下执行此操作,而仅使用控制器来切换页面。

顺便说一句,您在加载页面时会创建导航栏的新实例,这是不正确的做法

答案 1 :(得分:0)

这是因为library(ggplot2) #mutate(Group = ifelse(whether.he.she.donated.blood.in.March.2007 == 0, "Didn't donate", "Donated")) %>% ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) + #scale_y_continuous(breaks = seq(0, 500, by = 100)) + #ylab("Count of people") + #ggtitle("People who donated blood in march 2007") + geom_bar() + geom_label(aes(label = after_stat(count)), stat = "count") 是一个自己的类,当您在此处调用PageNavigationBar时,只有该类会更新

看看Provider 一个非常有用的状态管理包

或者当setstateNavBar且只有一页时,您也可以处理页面

Main Page

答案 2 :(得分:0)

您不需要使用导航器来更改页面,我只是尝试修改了代码。

import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(home: PageNavigationBar()));
}

class PageNavigationBar extends StatefulWidget {
  @override
  _PageNavigationBarState createState() => _PageNavigationBarState();
}

class _PageNavigationBarState extends State<PageNavigationBar> {
  //default page showing in bottom navigation bar will be CookRecipe()
  int _selectedPage = 1;

//all pages optional in bottom navigation bar
  final List<Widget> _pageOptions = [
    HomePage(),
    CookRecipe(),
  ];

  void onTapped(int pageTapped) {
    setState(() {
      //print(pageTapped);
      _selectedPage = pageTapped;
//      Navigator.push(context, MaterialPageRoute(builder: (context) => _pageOptions[pageTapped]));
      //print(_selectedPage);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pageOptions[_selectedPage],
      bottomNavigationBar: BottomNavigationBar(
        //TODO: currentIndex: doesn't update when the state updates, why?
        currentIndex: _selectedPage,
        //items showing in bottom navigation bar
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Homepage'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            title: Text('Search recipe'),
          ),
        ],
        onTap: (int pageTapped) {
          onTapped(pageTapped);
        },
      ),
    );
  }
}

class CookRecipe extends StatefulWidget {
  @override
  _CookRecipeState createState() => _CookRecipeState();
}

class _CookRecipeState extends State<CookRecipe> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('Search recipes'),
    );
  }
}

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

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('Home page'),
    );
  }
}