flutter中的透明底部导航栏

问题描述 投票:0回答:12

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

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

我试过使用

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

但这似乎行不通。请帮忙。

dart flutter flutter-layout
12个回答
72
投票

给出的答案都不适合我,我发现了一些非常重要的事情:你必须添加属性

extendBody: true

如果为真,并且指定了 bottomNavigationBar 或 persistentFooterButtons,则主体会延伸到脚手架的底部,而不是仅延伸到 bottomNavigationBar 或 persistentFooterButtons 的顶部。

当 bottomNavigationBar 具有非矩形形状时,此属性通常很有用,例如 CircularNotchedRectangle,它将 FloatingActionButton 大小的凹口添加到栏的顶部边缘。在这种情况下,指定 extendBody: true 可确保通过底部导航栏的槽口可见脚手架的主体

连同

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 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
                        ),
                    ),
                ),
            );
        }
    }

希望对您有所帮助


21
投票

我尝试使用评论中讨论的 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: () {},),
                ],)),


8
投票

我就是这样实现的

    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,
    );

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

canvasColor: Colors.transparent

希望这会有所帮助。

快乐的编码!


5
投票

在新版本的 flutter(1.2.1) 中有一个 elevation 参数,你可以把 海拔:0.0


3
投票

这是我的方法:

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
.

对齐的列内的底部导航栏填充整个屏幕(图像纯粹是微不足道的,但你明白了)

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

深入思考,我意识到这不会带来同样的效果 结果符合预期,因为两个女孩的形象会在上面 导航栏。我建议使用带有两个女孩图像的 Stack 作为底层(堆栈底部)和全屏 Column MainAxisSize 设置为 MainAxisSize.max,MainAxisAlignment 设置为 MainAxisAlignment.end。我可以把它写在答案中,但我无法测试 现在,所以我更愿意写评论。希望有帮助

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

BottomNavigationBar
实现了自己的
Row

@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,
                    )),
              ],
            )
          ],
        )
      ],
    );

这是我手机的截图:

Example

奖金

调用即可实现全屏

SystemChrome.setEnabledSystemUIOverlays([]);

来源:这里


1
投票

我的高层解决方案:

  @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()),
          )
        ],
      ),
    );

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


0
投票
Scaffold(  
  floatingActionButton: _buildTransparentButton()
)

你可以试试 floatingActionButton.


0
投票

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

backgroundColor: const Color(0x00FFFFFF)

0x00 = 0% 不透明度


0
投票

BottomNavigationBar 非常简单

只在BottomNavigationBar中添加这些属性即可,

backgroundColor: Color(0x00ffffff),
elevation: 0,
type: BottomNavigationBarType.fixed,

添加这些后我的代码看起来像这样。

BottomNavigationBar(
selectedItemColor: MyTheme.primary_color,
unselectedItemColor: Color.fromRGBO(153, 153, 153, 1),
backgroundColor: Color(0x00ffffff),
elevation: 0,
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
onTap: (index) {
_currentIndex = index;                  
},
items: [

0
投票

2022 解决方案 非常非常简单

1 - 透明色 2 - 零海拔

BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          backgroundColor: Colors.transparent,
          elevation: 0,

0
投票

我使用了BottomNavigationBar命令,但是运行命令时的问题不起作用,显示为错误。我不知道现实中的解决方案是什么,因为我已经用尽了所有可能的方法


-4
投票

找到透明的解决方案

BottomNavigationBar
.

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

现在你得到一个透明的

BottomNavigationBar

© www.soinside.com 2019 - 2024. All rights reserved.