颤动中的透明底部导航栏

Transparent bottom navigation bar in flutter

我是 Flutter 新手。我正在努力实现这个 UI

我还没有找到任何使用完整的解决方案来创建 flutter 中的透明底部导航栏。

我试过使用

BottomNavigationBarItem(
        backgroundColor: Colors.transparent,
        icon: e,
        activeIcon: _activeIcons[_index],
        title: Text(
          title[_index],
          style: AppStyle.tabBarItem,
        ),
      )

但这似乎不起作用。请帮忙。

我尝试使用评论中讨论的 Stack 方法:

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Stack(
          children: <Widget>[
            Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage('assets/background.jpg'),
                    fit: BoxFit.cover),
              ),
            ),
            Align(
                alignment: Alignment.bottomCenter,
                child: Theme(
                    data: Theme.of(context)
                        .copyWith(canvasColor: Colors.transparent),
                    child: BottomNavigationBar(
                      currentIndex: 0,
                      items: [
                        BottomNavigationBarItem(
                            icon: Icon(Icons.home), title: Text('Home')),
                        BottomNavigationBarItem(
                            icon: Icon(Icons.home), title: Text('Home')),
                        BottomNavigationBarItem(
                            icon: Icon(Icons.home), title: Text('Home'))
                      ],
                    ))),
          ],
        ),
      ),
    );
  }

编辑:BottomNavigationBar 有一个内置的 8.0 高度,您无法更改它并导致奇怪的阴影效果。如果你想删除它,你可以像这样实现你自己的底部栏:

Align(
                alignment: Alignment.bottomCenter,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                  IconButton(icon: Icon(Icons.home, color: Theme.of(context).accentColor,), onPressed: () {},),
                  IconButton(icon: Icon(Icons.home, color: Theme.of(context).accentColor,), onPressed: () {},),
                  IconButton(icon: Icon(Icons.home, color: Theme.of(context).accentColor,), onPressed: () {},),
                ],)),

这是我的方法:

Stack(
      children: <Widget>[
        Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              fit: BoxFit.fill,
              image: NetworkImage("https://cdn.pixabay.com/photo/2018/09/17/16/24/cat-3684184_960_720.jpg")
            )
          ),
        ),
        Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Theme(
              data: Theme.of(context).copyWith(canvasColor: Colors.transparent),
              child: BottomNavigationBar(
                items: [
                  BottomNavigationBarItem(
                      icon: Icon(Icons.photo_camera), title: Text("Test")),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.photo_camera), title: Text("Test")),
                ],
              ),
            )
          ],
        )
      ],
    );

这将用背景图像(底层)和内容与 end 对齐的列中的底部导航栏填充整个屏幕(图像纯粹是微不足道的,但你明白了)。

为了完成目的,我将把我在原始问题的评论中给出的解释粘贴在下面。

Thinking deeper, I'm realizing that this would not deliever the same result as the desired, since the image of the two girls would be above the NavigationBar. I suggest to use a Stack with the two girls image as the bottom layer (bottom of the stack) and a full screen Column with MainAxisSize set to MainAxisSize.max and MainAxisAlignment set to MainAxisAlignment.end. I could write it in an answer but I cannot test it right now, so I prefer to write a comment instead. Hope it helps

更新 以前的解决方案仍然有导航栏阴影。 这个屏幕(小部件)的构建方法没有,因为我已经用 Row:

实现了我自己的 BottomNavigationBar
@override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
          decoration: BoxDecoration(
              image: DecorationImage(
                  fit: BoxFit.fill,
                  image: NetworkImage(
                      "https://media.idownloadblog.com/wp-content/uploads/2016/04/macinmac-portrat-splash.jpg"))),
        ),
        Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                GestureDetector(
                    onTap: () {
                      print("Tap!");
                    },
                    child: Icon(
                      Icons.photo_camera,
                      size: 50,
                    )),
                GestureDetector(
                    onTap: () {
                      print("Tap!");
                    },
                    child: Icon(
                      Icons.photo_camera,
                      size: 50,
                    )),
                GestureDetector(
                    onTap: () {
                      print("Tap!");
                    },
                    child: Icon(
                      Icons.photo_camera,
                      size: 50,
                    )),
                GestureDetector(
                    onTap: () {
                      print("Tap!");
                    },
                    child: Icon(
                      Icons.photo_camera,
                      size: 50,
                    )),
              ],
            )
          ],
        )
      ],
    );

这是我的 phone:

的屏幕截图

奖金

调用即可实现全屏

SystemChrome.setEnabledSystemUIOverlays([]);

来源:

我的高级解决方案:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          SingleChildScrollView(
            child: Center(
              child: Column(
                children: <Widget>[
                  child(),
                  child(),
                  child(),
                  child(),
                  child(),
                ],
              ),
            ),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: Opacity(opacity: showBottomBar ? 1 : 0, child: bottomBar()),
          )
        ],
      ),
    );

这个想法是一个堆栈,在较低级别有一个可滚动的视图,在它的顶部有一个对齐的自定义底部栏

找到透明 BottomNavigationBar 的解决方案。

  1. 使用快捷键 Ctrl+B.
  2. 打开 BottomNavigationBar 的源代码
  3. 滚动浏览文件,您会发现一个名为 Widget build.
  4. 的方法
  5. 在那上面你可以找到一个 Stack widget 在那里你可以找到一个 material 小部件。
  6. 添加shadowColor:Colors.transparent

现在你得到一个透明的BottomNavigationBar

新版本的flutter(1.2.1)有一个elevation的参数,你可以直接放 海拔:0.0

我就是这样实现的

    return Scaffold(
      body: Builder(
        builder: (context) => Container(
          decoration: bgAuthenticationDecoration(),
          child: _HomeBodyWidget(_currentIndex),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(icon: Icon(Icons.home,),title: Container()),
        BottomNavigationBarItem(icon: Icon(Icons.message),title: Container()),
        BottomNavigationBarItem(icon: Icon(Icons.list),title: Container()),
        BottomNavigationBarItem(icon: Icon(Icons.favorite),title: Container()),
        BottomNavigationBarItem(icon: Icon(Icons.supervised_user_circle),title: Container()),
      ],
      backgroundColor:Colors.black.withOpacity(0.1),),
      extendBodyBehindAppBar: true,
      extendBody: true,
    );

然后你必须在应用程序主题中将 canvas 颜色设置为透明。

canvasColor: Colors.transparent

希望这会有所帮助。

编码愉快!

None 的给定答案对我有用,我发现了一些非常重要的事情:你必须添加 属性 extendBody: true

If true, and bottomNavigationBar or persistentFooterButtons is specified, then the body extends to the bottom of the Scaffold, instead of only extending to the top of the bottomNavigationBar or the persistentFooterButtons.

This property is often useful when the bottomNavigationBar has a non-rectangular shape, like CircularNotchedRectangle, which adds a FloatingActionButton sized notch to the top edge of the bar. In this case specifying extendBody: true ensures that that scaffold's body will be visible through the bottom navigation bar's notch

连同 backgroundColor: Color(0x00ffffff), .

注意:0x 的颜色是十六进制的 ARGB 值(0xAARRGGBB),所以 ffffff 前的 00 表示最大透明度,您可以通过将 00 增加到 ff(十六进制为 255)来增加不透明度。

完整代码示例:

import 'package:flutter/material.dart';

class NavigationBar extends StatefulWidget {
  static int _selectedIndex = 0;

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

class NavigationBarState extends State<NavigationBar> {
  void _onItemTapped(int index) {
    setState(() {
      NavigationBar._selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {

    return BottomNavigationBar(
        elevation: 0, // to get rid of the shadow
        currentIndex: NavigationBar._selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
        backgroundColor: Color(0x00ffffff), // transparent, you could use 0x44aaaaff to make it slightly less transparent with a blue hue.
        type: BottomNavigationBarType.fixed,
        unselectedItemColor: Colors.blue,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.grade),
            label: 'Level',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.notifications),
            label: 'Notification',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'Achievements',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            label: 'Settings',
          ),
        ]
    );
  }

  @override
  Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

然后你有 MaterialApp return:

return MaterialApp(
                home: Scaffold(
                    extendBody: true, // very important as noted
                    bottomNavigationBar: NavigationBar(), // here you make use of the transparent bar.
                    body: Container(
                        decoration: BoxDecoration(
                            image: DecorationImage(
                                image: ExactAssetImage("assets/background.png"), // because if you want a transparent navigation bar I assume that you have either a background image or a background color. You need to add the image you want and also authorize it in pubspec.yaml
                                fit: BoxFit.fill
                            ),
                        ),
                        child: Container(
                              // the body of your app
                        ),
                    ),
                ),
            );
        }
    }

希望对您有所帮助。

你可以做类似...

不要忘记设置 elevation: 0 并使用 import 'package:flutter/services.dart';

隐藏状态栏

void main() {
  SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
  runApp(MaterialApp(
     home: MyApp()));
}

BottomNavigationBar透明

BottomNavigationBar(
  backgroundColor: Colors.black.withOpacity(0.1), //here set your transparent level
  elevation: 0,
);

这里是完整的代码

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Stack(
      children: <Widget>[
        Container(
         child: Image.network("https://picsum.photos/660/1420"),
        ),
        Align(
            alignment: Alignment.bottomCenter,
            child: BottomNavigationBar(
              backgroundColor: Colors.black.withOpacity(0.1), //here set your transparent level
              elevation: 0,
              selectedItemColor:  Colors.blueAccent,
              unselectedItemColor: Colors.white,
              type: BottomNavigationBarType.fixed,
              currentIndex: 0,
              showSelectedLabels: false,
              showUnselectedLabels: false,
              items: [
                BottomNavigationBarItem(
                    icon: Icon(Icons.notifications_none, size: 30), title: Text('Notifications')),
                BottomNavigationBarItem(
                    icon: Icon(Icons.search, size: 30), title: Text('Search')),
                BottomNavigationBarItem(
                    icon: Icon(Icons.perm_identity, size: 30), title: Text('User'))
              ],
            )),
      ],
    ),
  );
}

Scaffold(  
  floatingActionButton: _buildTransparentButton()
)

你可以试试floatingActionButton。

我通过为背景色指定透明度解决了这个问题:

backgroundColor: const Color(0x00FFFFFF)

0x00 = 0% 不透明度