前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter布局基础——自定义BottomNavigationBar

Flutter布局基础——自定义BottomNavigationBar

原创
作者头像
莫空9081
修改2021-08-19 14:53:17
1.8K0
修改2021-08-19 14:53:17
举报
文章被收录于专栏:iOS 备忘录iOS 备忘录

Flutter布局基础——自定义BottomNavigationBar

背景

这里我们来尝试实现一个不规则的 BottomNavigationBar,首先了解两个系统组件: floatingActionButtonBottomAppBar

<!--more-->

floatingActionButton

floatingActionButton用于创建一个浮动的按钮,有两种样式:一种是圆形的纯图标的;一种是椭圆的带有图标或文案的。

示例如下:

代码语言:txt
复制
void main() => runApp(const MyApp());

/// This is the main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

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

/// This is the stateless widget that the main application instantiates
class MyStatelessWidget extends StatelessWidget {
  const MyStatelessWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Floating Action Button'),
      ),
      body: const Center(
        child: Text('Press the button below'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Add your onPressed code here!
        },
        child: const Icon(Icons.navigation),
        backgroundColor: Colors.green,
      ),
    );
  }
}

显示效果:

<!--<img src="https://inews.gtimg.com/newsapp\_ls/0/13897745469/0.png" style="width:200px" />-->

simulator screen shot - iphone 12 pro max - 2021-08-19 at 10.44.05.png
simulator screen shot - iphone 12 pro max - 2021-08-19 at 10.44.05.png
代码语言:txt
复制
void main() => runApp(const MyApp());

/// This is the main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

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

/// This is the stateless widget that the main application instantiates
class MyStatelessWidget extends StatelessWidget {
  const MyStatelessWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Floating Action Button Label'),
      ),
      body: const Center(
        child: Text('Press the button width a label below!'),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          // Add your onPressed code here!
        },
        label: const Text('Approve'),
        icon: const Icon(Icons.thumb_up),
        backgroundColor: Colors.pink,
      ),
    );
  }
}

显示效果:

<!--<img src="https://inews.gtimg.com/newsapp\_ls/0/13897745453/0.png" style="width:200px" />-->

simulator screen shot - iphone 12 pro max - 2021-08-19 at 10.43.45.png
simulator screen shot - iphone 12 pro max - 2021-08-19 at 10.43.45.png

BottomAppBar

要实现的效果如下:

<!--<img src="https://inews.gtimg.com/newsapp\_ls/0/13898273707/0.png" style="width:200px" />-->

simulator screen shot - iphone 12 pro max - 2021-08-19 at 13.54.17.png
simulator screen shot - iphone 12 pro max - 2021-08-19 at 13.54.17.png

下面来分析如何实现:

body 是 ListView,ListView 的内容从上到下是:

  • 两个SwitchListTile
  • 一个Padding
  • 四个RadioListTile

再然后是 floatingActionButton

再然后是 BottomAppBar

如下:

<!--<img src="https://inews.gtimg.com/newsapp\_ls/0/13898292007/0.png" style="width:200px" />-->

企业微信20210819-140137@2x.png
企业微信20210819-140137@2x.png

代码如下:

代码语言:txt
复制
void main() {
  runApp(const BottomAppBarDemo());
}

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

  @override
  State createState() => _BottomAppBarDemoState();
}

class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
  bool _showFab = true;
  bool _showNotch = true;
  FloatingActionButtonLocation _fabLocation =
      FloatingActionButtonLocation.endDocked;

  void _onShowNotchChanged(bool value) {
    setState(() {
      _showNotch = value;
    });
  }

  void _onShowFabChanged(bool value) {
    setState(() {
      _showFab = value;
    });
  }

  void _onFabLocationChanged(FloatingActionButtonLocation? value) {
    setState(() {
      _fabLocation = value ?? FloatingActionButtonLocation.endDocked;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          title: const Text('Bottom App Bar Demo'),
        ),
        body: ListView(
          padding: const EdgeInsets.only(bottom: 88),
          children: <Widget>[
            SwitchListTile(
              value: _showFab,
              onChanged: _onShowFabChanged,
              title: const Text('Floating Action Button'),
            ),
            SwitchListTile(
              value: _showNotch,
              onChanged: _onShowNotchChanged,
              title: const Text('Notch'),
            ),
            const Padding(
              padding: EdgeInsets.all(16),
              child: Text('Floating action button position'),
            ),
            RadioListTile(
              value: FloatingActionButtonLocation.endDocked,
              groupValue: _fabLocation,
              onChanged: _onFabLocationChanged,
              title: const Text('Docked - End'),
            ),
            RadioListTile(
              value: FloatingActionButtonLocation.centerDocked,
              groupValue: _fabLocation,
              onChanged: _onFabLocationChanged,
              title: const Text('Docked - Center'),
            ),
            RadioListTile(
              value: FloatingActionButtonLocation.endFloat,
              groupValue: _fabLocation,
              onChanged: _onFabLocationChanged,
              title: const Text('Floating - End'),
            ),
            RadioListTile(
              value: FloatingActionButtonLocation.centerFloat,
              groupValue: _fabLocation,
              onChanged: _onFabLocationChanged,
              title: const Text('Floating - Center'),
            ),
          ],
        ),
        floatingActionButton: _showFab
            ? FloatingActionButton(
                onPressed: () {},
                child: const Icon(Icons.add),
                tooltip: 'Create',
              )
            : null,
        floatingActionButtonLocation: _fabLocation,
        bottomNavigationBar: _DemoBottomAppBar(
            fabLocation: _fabLocation,
            shape: _showNotch ? const CircularNotchedRectangle() : null),
      ),
    );
  }
}

class _DemoBottomAppBar extends StatelessWidget {
  const _DemoBottomAppBar({
    this.fabLocation = FloatingActionButtonLocation.endDocked,
    this.shape = const CircularNotchedRectangle(),
  });

  final FloatingActionButtonLocation fabLocation;
  final NotchedShape? shape;

  static final List<FloatingActionButtonLocation> centerLocations =
      <FloatingActionButtonLocation>[
    FloatingActionButtonLocation.centerDocked,
    FloatingActionButtonLocation.centerFloat,
  ];

  @override
  Widget build(BuildContext context) {
    return BottomAppBar(
      shape: shape,
      color: Colors.blue,
      child: IconTheme(
        data: IconThemeData(color: Theme.of(context).colorScheme.onPrimary),
        child: Row(
          children: <Widget>[
            IconButton(
              tooltip: 'Open navigation menu',
              icon: const Icon(Icons.menu),
              onPressed: () {},
            ),
            if (centerLocations.contains(fabLocation)) const Spacer(),
            IconButton(
              tooltip: 'Search',
              icon: const Icon(Icons.search),
              onPressed: () {},
            ),
            IconButton(
              tooltip: 'Favorite',
              icon: const Icon(Icons.favorite),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}

要注意floatingActionButtonLocation的设置

参考

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Flutter布局基础——自定义BottomNavigationBar
    • 背景
      • floatingActionButton
      • BottomAppBar
    • 参考
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档