dart 在选项卡视图主体中导航Flutter

unguejic  于 12个月前  发布在  Flutter
关注(0)|答案(2)|浏览(104)

该应用程序包含TabBar和BottomNavigationBar。当我试图在标签栏视图中导航时,它会全屏导航。
这是我试图得到的结果时,点击按钮-Expected Result
但我得到了这个Current Output
在这里我附上了代码-

Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Traveler"),
            bottom: new TabBar(controller: _controller, tabs: <Tab>[
              new Tab(text: "NEW"),
              new Tab(text: "HOTELS"),
              new Tab(text: "FOOD"),
              new Tab(text: "FUN"),
            ]),
          ),
          body: new TabBarView(
            controller: _controller,
            children: <Widget>[
              new NewPage(_index),
              new HotelsPage(_index),
              new FoodPage(_index),
              new FunPage(_index),
            ],
          ),
          bottomNavigationBar: new BottomNavigationBar(
              currentIndex: _index,
              onTap: (int _index) {
                setState(() {
                  this._index = _index;
                });
              },
              items: <BottomNavigationBarItem>[
                new BottomNavigationBarItem(
                  icon: new Icon(Icons.home),
                  title: new Text("Home"),
                ),
                new BottomNavigationBarItem(
                  icon: new Icon(Icons.favorite),
                  title: new Text("Favorites"),
                ),
              ]),
        );
      }
    }
    
    class NewPage extends StatelessWidget {
      final int index;
    
      NewPage(this.index);
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: RaisedButton(
            onPressed: (){
               Navigator.push(context,MaterialPageRoute(builder: (context)=>InsideTabViewPage()), );
            },
            child: new Text('NewPage, index: $index')),
        );
      }
    }
vuktfyat

vuktfyat1#

您可以通过创建一个新的Navigator小部件来实现这一点,该小部件位于主应用程序导航器下的某个位置,
下面是测试示例:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark().copyWith(
        elevatedButtonTheme: ElevatedButtonThemeData(
            style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all(Colors.blueGrey[800]),
        )),
      ),
      home: MyApp()));
}

//Store this globally
final GlobalKey<NavigatorState> _navKey = GlobalKey<NavigatorState>();

class MyApp extends StatefulWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  late final TabController _tabController;
  @override
  void initState() {
    _tabController = TabController(length: 2, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Nested Navigator'),
        bottom: TabBar(
          controller: _tabController,
          tabs: [
            Tab(
              child: Text('First Tab'),
            ),
            Tab(
              child: Text('Second Tab'),
            ),
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(
              icon: Icon(Icons.favorite), label: 'Favorites'),
        ],
      ),
      body: Navigator(
        key: _navKey,
        onGenerateRoute: (_) => MaterialPageRoute(
          builder: (_) => TabBarView(
            controller: _tabController,
            children: [
              FirstPage(),
              SecondPage(),
            ],
          ),
        ),
      ),
    );
  }
}

class FirstPage extends StatelessWidget {
  const FirstPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('First Page'),
            ElevatedButton(
                onPressed: () {
                  _navKey.currentState!.push(
                    MaterialPageRoute(
                      builder: (_) => SubFirstPage(),
                    ),
                  );
                },
                child: Text('Go to Nested Page 1'))
          ],
        ),
      ),
    );
    ;
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Second Page'),
            ElevatedButton(
              onPressed: () {
                _navKey.currentState!.push(
                  MaterialPageRoute(
                    builder: (_) => SubSecondPage(),
                  ),
                );
              },
              child: Text('Go to Nested Page 2'),
            )
          ],
        ),
      ),
    );
  }
}

class SubFirstPage extends StatelessWidget {
  const SubFirstPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Nested Page'),
      ),
      body: Center(
        child: Text('From First Page'),
      ),
    );
  }
}

class SubSecondPage extends StatelessWidget {
  const SubSecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Nested Page'),
      ),
      body: Center(
        child: Text('From Second Page'),
      ),
    );
  }
}

结果是:

You can read more about nested navigation in Navigator 1.0 API here

pkbketx9

pkbketx92#

这个问题的一个好的解决方案是使用来自pub.devgo_router包,这是一个很棒的路由包,它是一个flutter favorite包
它专门解决了你所问的嵌套路由问题,通过实现他们称之为shell路由的东西,你基本上可以将你的应用程序的一些路由定义为拥有一个shell,这个shell可以是任何东西,比如在你的例子中,一个带有bottomNavigationBar的Scaffold,
当调用这样的路由时,导航将在该shell中发生(在导航期间该shell保持原位),使用独立于应用程序的根导航器的另一个导航器

相关问题