1

我有一个底部导航栏,可以在按下图标时导航到其他页面。这工作正常,除了当状态更新时,BottomNavigationBar 中的 currentIndex 属性的值不会更新,这意味着实际的 BottomNavigationBar 没有变化。在此处输入图像描述

我正在使用可变(_selectedPage)来跟踪BottomNavigationBar中的选定索引,并且在点击项目时值会发生变化,但是当状态更新时它不会更新currentIndex属性..这是为什么?

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(),
      ),
    );
  }
}

4

3 回答 3

1

我建议您创建一个小部件,该小部件将包含BottomNavigationBar并且还PageView允许您使用 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使用 , 并仅使用控制器来切换页面。

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

于 2020-04-15T15:53:40.850 回答
0

这是因为PageNavigationBar是一个自己的类,当你在那里调用时,setstate只有这个类更新

看看Provider 一个非常实用的状态管理Package

或者你也可以处理你的页面,当它NavBar是你的Main Page并且你只有一个页面时

return MaterialApp(
  home: Scaffold(
      appBar: ownAppBar(_selectedPage),
      body: _bodyOptions[_selectedPage],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedPage,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Homepage'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            title: Text('Search recipe'),
          ),
        ],
        onTap: (int pageTapped) {
          onTapped(pageTapped);
        },
      )
  ),
);



final List<Widget> _bodyOptions = [
    HomePage(),
    CookRecipe(),
  ];
于 2020-04-15T16:09:09.357 回答
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'),
    );
  }
}
于 2020-04-15T18:28:46.570 回答