【问题标题】:Flutter BottomNavigationBar and advanced navigationFlutter BottomNavigationBar 和高级导航
【发布时间】:2018-10-08 09:35:50
【问题描述】:

我正在构建一个底部导航栏中包含 3 个项目的应用。当我更改选项卡时,正在呈现不同的小部件。到目前为止,一切都很好......

import 'package:flutter/material.dart';

class BottomTest extends StatefulWidget {
  State createState() => new _BottomTestState();
}

class _BottomTestState extends State<BottomTest> {
  List<Widget> _pages;
  Widget _selectedContent;
  int _bottomIndex;

  @override
  void initState() {
    _bottomIndex = 0;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    _definePages();

    return Scaffold(
      appBar: AppBar(
        title: Text('Bottom Navigation Test'),
      ),
      body: _selectedContent ?? _pages[_bottomIndex],
      bottomNavigationBar: BottomNavigationBar(
            items: [
              BottomNavigationBarItem(
                  icon: Icon(Icons.add),
                  title: Text("Red")
              ),
              BottomNavigationBarItem(
                  icon: Icon(Icons.location_on),
                  title: Text("Blue")
              ),
              BottomNavigationBarItem(
                  icon: Icon(Icons.people),
                  title: Text("Green")
              )
            ],
            currentIndex: _bottomIndex,
            onTap: _onTabTapped,
        )
    );
  }

  _definePages() {
    _pages = [
      Container(
          color: Colors.red,
          child: Stack(children: <Widget>[
            _defineFloatingActionButton(),
          ])
      ),
      Container(color: Colors.blue),
      Container(color: Colors.green),
    ];
  }

  _defineFloatingActionButton() {
    return Align(
      alignment: Alignment.bottomRight,
      child: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () {
            //TODO: How to navigate to another page with still displaying the bottom navigation bar?
          }
      ),
    );
  }

  void _onTabTapped(int index) {
    setState(() {
      _bottomIndex = index;
      _selectedContent = _pages[index];
    });
  }
}

//POST
class Post extends StatefulWidget {
  State createState() => new _PostState();
}

class _PostState extends State<Post> {
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      PostHeader(),
      Text('This is a post.') 
    ]);
  }
}

//POSTHEADER
class PostHeader extends StatefulWidget {
  State createState() => new _PostHeaderState();
}

class _PostHeaderState extends State<PostHeader> {
  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: Text('Author'),
      onTap: () {
        //TODO: This should navigate to another page but still displaying the bottom navigation bar, too.
      },
    );
  }
}

但我想不出更高级导航的最佳做法。我目前面临两个问题。

  1. 当在第一页上切换 FloatingActionButton 时,我想显示第四页,但 BottomNavigationBar 仍然需要可见且可操作。

  2. 构建一个更复杂的应用程序,我正在处理一些嵌套类。所以在我的根页面上,有一个“Post”类,并且该帖子包含一个“PostHeader”类。在 PostHeader 中,有一个带有 onTap 回调的 ListTile,它应该会影响我的 _selectedContent。我如何定义这个回调?通过所有不同的类传递它似乎并不正确。

我考虑在我的 BottomTest.dart 中定义它并通过 Post 和 PostTile 传递它,但这对我来说似乎不是最佳实践,尤其是在谈到大量必需的回调时。

提前非常非常感谢您!

【问题讨论】:

  • 这是一个您可以阅读的博客,它讨论了您的问题 1,不确定问题 2。它讨论了使用 TabNavigator medium.com/coding-with-flutter/… 构建动态路由的一些技巧

标签: flutter flutter-layout


【解决方案1】:

我假设第四页将显示为其他三个页面中的任何一个,并且由于按钮位于第一页中,因此第四页将代替第一页,并且仍然指示第一个底部“红色” " 字段处于活动状态。

如果是这种情况,您应该为第一页创建一个独立的小部件,其中包含显示其他内容所需的所有逻辑。因此,您可以避免重建主布局,包括 BottomNavigationBar。

您可以通过使用FirstPage 小部件来使用这些方面的东西:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new BottomTest(),
    );
  }
}

class BottomTest extends StatefulWidget {
  State createState() => new _BottomTestState();
}

class _BottomTestState extends State<BottomTest> {
  List<Widget> _pages;
  Widget _selectedContent;
  int _bottomIndex;

  @override
  void initState() {
    _bottomIndex = 0;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    _definePages();

    return Scaffold(
        appBar: AppBar(
          title: Text('Bottom Navigation Test'),
        ),
        body: _selectedContent ?? _pages[_bottomIndex],
        bottomNavigationBar: BottomNavigationBar(
          items: [
            BottomNavigationBarItem(icon: Icon(Icons.add), title: Text("Red")),
            BottomNavigationBarItem(
                icon: Icon(Icons.location_on), title: Text("Blue")),
            BottomNavigationBarItem(
                icon: Icon(Icons.people), title: Text("Green"))
          ],
          currentIndex: _bottomIndex,
          onTap: _onTabTapped,
        ));
  }

  _definePages() {
    _pages = [
      FirstPage(),
      Container(color: Colors.blue),
      Container(color: Colors.green),
    ];
  }

  void _onTabTapped(int index) {
    setState(() {
      _bottomIndex = index;
      _selectedContent = _pages[index];
    });
  }
}

//POST
class Post extends StatefulWidget {
  State createState() => new _PostState();
}

class _PostState extends State<Post> {
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[PostHeader(), Text('This is a post.')]);
  }
}

//POSTHEADER
class PostHeader extends StatefulWidget {
  State createState() => new _PostHeaderState();
}

class _PostHeaderState extends State<PostHeader> {
  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: Text('Author'),
      onTap: () {
        //TODO: This should navigate to another page but still displaying the bottom navigation bar, too.
      },
    );
  }
}

class FirstPage extends StatefulWidget {
  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {

  bool showFirst = true;

  _defineFloatingActionButton() {
    return Align(
      alignment: Alignment.bottomRight,
      child: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: _onButtonPressed,
      ),
    );
  }

  _onButtonPressed() {
    setState(() {
      showFirst = !showFirst;
    });
  }

  _buildFirst() {
    return Container(
        color: Colors.red,
        child: Stack(children: <Widget>[
          _defineFloatingActionButton(),
        ]));
  }

  _buildFourth() {
    return Container(
        color: Colors.grey,
        child: Stack(children: <Widget>[
          _defineFloatingActionButton(),
        ]));
  }

  @override
  Widget build(BuildContext context) {
    return showFirst ? _buildFirst() : _buildFourth();
  }
}

对于第二点,也许您应该打开另一个问题,以便在不同的答案中保留两个或多或少不相关的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2019-09-17
    • 2021-08-21
    • 2020-11-06
    • 2021-06-18
    • 2020-09-18
    • 2021-10-13
    相关资源
    最近更新 更多