推到新屏幕时,使底部导航栏保持静态

时间:2019-02-19 13:20:06

标签: dart flutter

我是初学者,喜欢飞镖和飞镖。我一直在尝试在应用程序的三个不同页面上实现navigationBar。对于单个页面,切换效果很好,但是我在将所有页面上的活动和非活动标签状态保持不变时遇到问题。似乎当它导航到另一个页面时,我也失去了选项卡的活动状态。这是我的代码。

AppFooter.dart

import 'package:flutter/material.dart';

class AppFooter extends StatefulWidget {
  @override
  _AppFooterState createState() => _AppFooterState();
}

class _AppFooterState extends State<AppFooter> {
  int index = 0;
  @override
  Widget build(BuildContext context) {
    return new 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.green,
          textTheme: Theme.of(context)
              .textTheme
              .copyWith(caption: new TextStyle(color: Colors.grey))),
      child: new BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          currentIndex: index,
          onTap: (int index) {
            setState(() {
              this.index = index;
            });
          switch (index){
            case 0:  Navigator.of(context).pushNamed('/dashboard');
            break;
            case 1:  Navigator.of(context).pushNamed('/medical centre');
            break;
            case 2:  Navigator.of(context).pushNamed('/history');
            break;

          }

          },
          items: [
            new BottomNavigationBarItem(
                backgroundColor: Colors.white,
                icon: index==0?new Image.asset('assets/images/dashboard_active.png'):new Image.asset('assets/images/dashboard_inactive.png'),
                title: new Text('Dashboard', style: new TextStyle(fontSize: 12.0))),
           new BottomNavigationBarItem(
               backgroundColor: Colors.white,
               icon: index==1?new Image.asset('assets/images/medical_sevice_active.png'):new Image.asset('assets/images/medical_sevice_inactive.png'),
               title: new Text('Health Services', style: new TextStyle(fontSize: 12.0))),
            new BottomNavigationBarItem(
                icon: InkWell(
                  child: Icon(
                    Icons.format_align_left,
                   // color: green,
                    size: 20.0,
                  ),
                ),
                title: new Text('History', style: new TextStyle(fontSize: 12.0))),
          ]),
    );
  }
}

13 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,则需要在所有三个页面上都保留底部的导航栏。关于如何实现这一目标,有一篇写得很好的文章。您可以在此处找到详细信息。

https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf

https://github.com/bizz84/nested-navigation-demo-flutter

所有学分归原始作者所有。

答案 1 :(得分:1)

使用 PageView bottomNavigationBar

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'Flutter App';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: App(),
    );
  }
}

class App extends StatefulWidget {
  App({Key key}) : super(key: key);
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  PageController _myPage;
  var selectedPage;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PageView(
          physics: NeverScrollableScrollPhysics(),
          controller: _myPage,
          children: <Widget>[
            Center(
              child: Text("Another Page"),
            ),
            Center(
                child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text("Page 1"),
                RaisedButton(
                  onPressed: () {
                    _myPage.jumpToPage(0);
                    setState(() {
                      selectedPage = 0;
                    });
                  },
                  child: Text("Go to another page"),
                )
              ],
            )),
            Center(child: Text("Page 2")),
            Center(child: Text("Page 3")),
          ],
        ),
        bottomNavigationBar: BottomAppBar(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              IconButton(
                icon: Icon(Icons.home),
                color: selectedPage == 1 ? Colors.blue : Colors.grey,
                onPressed: () {
                  _myPage.jumpToPage(1);
                  setState(() {
                    selectedPage = 1;
                  });
                },
              ),
              IconButton(
                icon: Icon(Icons.star),
                color: selectedPage == 2 ? Colors.blue : Colors.grey,
                onPressed: () {
                  _myPage.jumpToPage(2);
                  setState(() {
                    selectedPage = 2;
                  });
                },
              ),
              IconButton(
                icon: Icon(
                  Icons.settings,
                ),
                color: selectedPage == 3 ? Colors.blue : Colors.grey,
                onPressed: () {
                  _myPage.jumpToPage(3);
                  setState(() {
                    selectedPage = 3;
                  });
                },
              ),
            ],
          ),
        ));
  }
}

希望有帮助。

答案 2 :(得分:1)

另一个很棒的解决方案是persistent_bottom_nav_bar提供的Bilal Shahid软件包。

易于使用,可为您提供features

  • 高度可定制的持久性底部导航栏。
  • 具有或不具有底部导航栏的新屏幕推送功能。
  • 底部导航栏的
  • 20种样式。
  • 包括用于推送带有或不带有底部导航栏的屏幕的功能,即pushNewScreen()和pushNewScreenWithRouteSettings()。
  • 基于flutter的Cupertino(iOS)底部导航栏。
  • 对于特定标签可以是半透明的。
  • 导航栏的自定义样式。点击这里查看更多信息。 处理硬件/软件Android后退按钮。

在找到此软件包之前,我遵循了他的回答中提到的@Abin文章中的解决方案。但是我遇到了一个问题,来自screens的所有navbar都是在navbar的第一次加载时加载的,而不是那个性能。我并不想解决这个问题,但是幸运的是,Bilal Shahid提供了一个很好的解决方案。

所有功劳归他所有。

答案 3 :(得分:1)

如果您正在寻找一种即使使用 IndexedStack 也能表现良好(不会不必要地构建标签/页面)的解决方案,请查看我的回答 here

答案 4 :(得分:0)

Navigator.of(context).pushNamed();用于带有页面过渡的导航。因此,在这种情况下,该方法不匹配。

您可以将BottomNavigationBarScaffold一起使用。

示例代码:


class AppFooter extends StatefulWidget {
  @override
  _AppFooterState createState() => _AppFooterState();
}

class _AppFooterState extends State<AppFooter> {
  int _currentIndex = 0;

  List<Widget> _pages = [
    Text("page1"),
    Text("page2"),
    Text("page3"),
  ];


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
        items: [
          new BottomNavigationBarItem(
              backgroundColor: Colors.white,
              icon: _currentIndex == 0
                  ? new Image.asset('assets/images/dashboard_active.png')
                  : new Image.asset('assets/images/dashboard_inactive.png'),
              title:
                  new Text('Dashboard', style: new TextStyle(fontSize: 12.0))),
          new BottomNavigationBarItem(
              backgroundColor: Colors.white,
              icon: _currentIndex == 1
                  ? new Image.asset('assets/images/medical_sevice_active.png')
                  : new Image.asset(
                      'assets/images/medical_sevice_inactive.png'),
              title: new Text('Health Services',
                  style: new TextStyle(fontSize: 12.0))),
          new BottomNavigationBarItem(
              icon: InkWell(
                child: Icon(
                  Icons.format_align_left,
                  // color: green,
                  size: 20.0,
                ),
              ),
              title: new Text('History', style: new TextStyle(fontSize: 12.0))),
        ],
      ),
    );
  }
}

答案 5 :(得分:0)

我正在研究express_app plugin的Beta版,该版本可以达到要求的结果。

两天前,我实现了一个附加功能,您可以在其中设置ExpressHome,并且可以设置树的任何部分,当然还可以设置路线。更改路线时,ExpressHome下的所有内容都只会更改,其余的都将保持不变(即您可以轻松拥有一个永久性酒吧。

今天晚上我将发布一个最新版本,如果您想了解有关您的用例的特定演示,请告诉我。

答案 6 :(得分:0)

我创建了一个很小的,超级易于使用的软件包,让您可以实现CustomNavigator的效果。 并在“您可以在here上找到它”上写了有关它的教程。

就这样

// Here's the custom scaffold widget
// It takes a normal scaffold with mandatory bottom navigation bar
// and children who are your pages
CustomScaffold(
  scaffold: Scaffold(
    bottomNavigationBar: BottomNavigationBar(
      items: _items,
    ),
  ),

  // Children are the pages that will be shown by every click
  // They should placed in order such as
  // `page 0` will be presented when `item 0` in the [BottomNavigationBar] clicked.
  children: <Widget>[
    Page('0'),
    Page('1'),
    Page('2'),
  ],

  // Called when one of the [items] is tapped.
  onItemTap: (index) {},
);

该库有效运行的妙处。它创建了一个嵌套的导航器(这样做非常不愉快),并将其用于窗口小部件树中的导航。 当然,您始终可以使用MaterialApp中的默认导航器

答案 7 :(得分:0)

您可以在触摸/更改页面时使用IndexedStack保持状态

Scaffold(
  body: SafeArea(
    top: false,
    child: IndexedStack(
      //Permet de garder le state des vues même quand on change de vue
      index: _currentIndex,
      children: _children,
    ),
  ),
  bottomNavigationBar: BottomNavigationBar( items: [ ] ),
);

答案 8 :(得分:0)

使用persistent_bottom_nav_bar

persistent_bottom_nav_bar管理各个选项卡的导航堆栈,使用此库,您可以在按下任何屏幕时管理{/ {1}}的隐藏/显示

答案 9 :(得分:0)

我强烈推荐使用堆栈。这使您可以完全控制显示底部应用栏的方式和时间。

使用botttomAppBar 列出要显示的所有页面。假设有三个图标。

Argument of type 'any[]' is not assignable to parameter of type 'SetStateAction<never[]>'.
Type 'any[]' is not assignable to type 'never[]'.
Type 'any' is not assignable to type 'never'.ts(2345)

在构建方法中

final List<Widget> pages=[FirstScreen(),SecondScreen(),ThirdScreen()];

其中 cur_ind 是用于控制显示哪个页面的变量。并且由于主体是堆叠的,因此 Scaffold( child: Stack( children: <Widget>[ Navigator( key: _navigatorKey, onGenerateRoute: (RouteSettings settings) { return MaterialPageRoute( builder: (BuildContext context) => pages[cur_ind], ); }, ), ], bottomNavigationBar: BottomNavigationBar( onTap: (int index){ setState(() { cur_ind=index; }); }, currentIndex: cur_ind, fixedColor: Colors.green, //let's say items: [ BottomNavigationBarItem( icon: Icon(Icons.home), title: Text('Home'), ), BottomNavigationBarItem( icon: Icon(Icons.mail), title: Text('Messages'), ), BottomNavigationBarItem( icon: Icon(Icons.person), title: Text('Profile')) ], ), ), ), 将始终保持不变。

答案 10 :(得分:0)

我也有这个问题...经过几天的研究,我发现了这个包 持久底部导航栏:^4.0.0

很容易实现。

答案 11 :(得分:0)

您可以使用脚手架小部件来包含整个屏幕,然后将 IndexedStack 小部件作为 Body 选项,然后在您最喜欢的底部导航栏实现的脚手架小部件中的底部导航选项中使用

Scaffold(
      // here is the IndexedStack as body
      body: IndexedStack(
          index: this._bottomNavIndex,
          children: [MangaGridView(), FavoriteManga()]),
      backgroundColor: Colors.black,
      bottomNavigationBar: AnimatedBottomNavigationBar(
        icons: [
          Icons.home_outlined,
          Icons.favorite_border,
          Icons.settings,
        ],
        inactiveColor: Colors.black,
        activeIndex: this._bottomNavIndex,
        gapLocation: GapLocation.none,
        activeColor: Theme.of(context).primaryColor,
        notchSmoothness: NotchSmoothness.verySmoothEdge,
        leftCornerRadius: 32,
        rightCornerRadius: 32,
        onTap: (index) => setState(() => this._bottomNavIndex = index),
        height: 70,
        splashColor: Theme.of(context).primaryColor,
        splashRadius: 40.0,
        splashSpeedInMilliseconds: 400,
        iconSize: 34,
      ),
    );

答案 12 :(得分:-2)

只需将索引变量设为静态 像:

static int index = 0;