Flutter AppBar的渐变背景

60

我该如何将AppBarbackgroundColor设置为渐变色?


对于其他人,请访问https://pub.dev/packages/gradientscaffoldwidget。 - Hussnain Haidar
3
你可以使用AppBar中的flexibleSpace属性来实现渐变背景。 - darwin
1
请查看此链接:https://hackernoon.com/flutter-gradient-app-bar-jm8a32fu - Daniel Vilela
7个回答

69

这应该无缝地工作:

return Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
    flexibleSpace: Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: <Color>[Colors.black, Colors.blue]),
      ),
    ),
  ),
);

这是正确的答案,因为它不会覆盖默认应用栏小部件的位置。使用此解决方案,您现有的操作按钮和返回按钮将继续工作。真正无瑕疵!谢谢! - Myo Win
这是最好的方法。谢谢! - Akaanksh K
这正是我正在寻找的。谢谢。 - undefined

54

我不相信你可以将渐变传递给AppBar,因为它期望的是颜色而不是渐变。

但是,您可以创建自己的小部件,模仿AppBar,只需使用渐变即可。请查看我从Planets-Flutter教程中整理出来的示例以及下面的代码。

输入图像描述

import "package:flutter/material.dart";

class Page extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(children : <Widget>[GradientAppBar("Custom Gradient App Bar"), Container()],);
  }
}


class GradientAppBar extends StatelessWidget {

  final String title;
  final double barHeight = 50.0;

  GradientAppBar(this.title);

  @override
  Widget build(BuildContext context) {
    final double statusbarHeight = MediaQuery
        .of(context)
        .padding
        .top;

    return new Container(
      padding: EdgeInsets.only(top: statusbarHeight),
      height: statusbarHeight + barHeight,
      child: Center(
        child: Text(
          title,
          style: TextStyle(fontSize: 20.0, color: Colors.white, fontWeight: FontWeight.bold),
        ),
      ),
      decoration: BoxDecoration(
        gradient: LinearGradient(
            colors: [Colors.red, Colors.blue],
            begin: const FractionalOffset(0.0, 0.0),
            end: const FractionalOffset(0.5, 0.0),
            stops: [0.0, 1.0],
            tileMode: TileMode.clamp
        ),
      ),
    );
  }
}

希望这可以帮到你。如果你有任何问题,请告诉我。


9
这不会有问题吗?因为AppBar的所有其他默认行为都需要重新编写。以导航的返回按钮为例,这个假设正确吗? - Giacomo Cerquone
3
使用这个库似乎是最终解决方案:https://github.com/joostlek/GradientAppBar - Mohamed Mo Kawsara
我们如何同时隐藏状态栏和黑色透明层? - Nilesh Rathore
可以使用PreferredSizeWidget将GradientAppBar直接设置为appBar。 - nivesh shastri
非常感谢,兄弟!!!你刚刚节省了我的时间 <3 - Nghien Nghien
显示剩余2条评论

17

默认情况下,AppBar不具备该功能。但是,您可以创建一个类似于AppBar的小部件,并具有渐变背景,如下所示:

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new PreferredSize(
        child: new Container(
          padding: new EdgeInsets.only(
            top: MediaQuery.of(context).padding.top
          ),
          child: new Padding(
            padding: const EdgeInsets.only(
              left: 30.0,
              top: 20.0,
              bottom: 20.0
            ),
            child: new Text(
              'Arnold Parge',
              style: new TextStyle(
                fontSize: 20.0,
                fontWeight: FontWeight.w500,
                color: Colors.white
              ),
            ),
          ),
          decoration: new BoxDecoration(
            gradient: new LinearGradient(
              colors: [
                Colors.red,
                Colors.yellow
              ]
            ),
            boxShadow: [
              new BoxShadow(
                color: Colors.grey[500],
                blurRadius: 20.0,
                spreadRadius: 1.0,
              )
            ]
          ),
        ),
        preferredSize: new Size(
          MediaQuery.of(context).size.width,
          150.0
        ),
      ),
      body: new Center(
        child: new Text('Hello'),
      ),
    );
  }

这里的boxShadow属性将会给予一种凸显感。


6
这个答案很好,我点赞了它,但是它不支持抽屉和其他原生的AppBar功能。这个库非常棒:https://github.com/joostlek/GradientAppBar - Mohamed Mo Kawsara
7
可以只使用Appbar实现。请参考以下链接:https://hackernoon.com/flutter-gradient-app-bar-jm8a32fu - Sumit Kumar
这不是一个AppBar。它只是一个带有渐变背景的容器。真正的AppBars可以与抽屉API、导航API(用于默认弹出)、灵活的空间和底部一起使用TabBar小部件等工作。 - dilshan

3

只需将AppBar放在Widgets Material > Container with grandient中,您就可以保留原始AppBar的属性。这是我的实现与必要的属性。

import 'package:flutter/material.dart';

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
  const CustomAppBar({
    Key? key,
    this.title,
    this.leading,
    this.actions,
    this.elevation = 2.0,
  }) : super(key: key);
  final Widget? title;
  final Widget? leading;
  final double elevation;
  final List<Widget>? actions;

  @override
  Widget build(BuildContext context) {
    return Material(
      elevation: elevation,
      child: Container(
        decoration: const BoxDecoration(
          gradient: RadialGradient(
            radius: 2.5,
            stops: [
              0.0,
              0.27,
              1.0,
            ],
            colors: [
              Color(0XFFB71731),
              Color(0XFFB71731),
              Color(0XFFA5004E),
            ],
          ),
        ),
        child: AppBar(
          centerTitle: true,
          leading: leading,
          elevation: 0.0,
          title: title,
          backgroundColor: Colors.transparent,
          actions: actions,
        ),
      ),
    );
  }

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

然后,您只需要在需要的地方使用它即可。

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

  @override
  Widget build(BuildContext context) {

        return Scaffold(
            appBar: const CustomAppBar(),
            body: Center(child:Text("My App gradient"),
        );
  }
}

3

您可以使用 flexibleSpace 进行装饰

appBar: AppBar(
      centerTitle: true,
        title: Text(widget.title),
        flexibleSpace: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topLeft,
                end: Alignment.bottomRight,
                colors: <Color>[
              Colors.red,
              Colors.blue
            ])          
         ),        
     ),      
 ),

1
在标准的AppBar中将背景和阴影颜色设置为Colors.transparent,然后用Container(...)将其包裹起来,使用BoxDecoration(gradient: LinearGradient(...)),完成之后一切都将如你所愿。
import 'package:flutter/material.dart';
import 'package:pga_app/core/colors.dart';

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
  const CustomAppBar({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    TextTheme thm = Theme.of(context).textTheme;
    return Container(
      child: AppBar(
        automaticallyImplyLeading: true,
        backgroundColor: Colors.transparent,
        shadowColor: Colors.transparent,
        title: const Text(
          "My Cool App",
          textAlign: TextAlign.center,
        ),
        actions: [
          TextButton(
            child: const Icon(Icons.menu, size: 36, color: COLOR_BUTTON_WHITE),
            onPressed: () {},
          ),
        ],
      ),
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          stops: [0.0, 1.0],
          colors: [
            COLOR_PANEL_DARK_BLUE,
            COLOR_PANEL_BLUE,
          ],
        ),
      ),
    );
  }

  @override
  Size get preferredSize => Size(900, 56);
}

请原谅我在这篇文章中使用了未定义的常量;这是从一个生产应用程序中提取出来的,名称已更改以保护无辜者。

Screen cap showing gradient in app bar


1
另一个答案出了些问题,不知道为什么。这个方法可行!非常感谢,我觉得这是最简单和最直观的。做得很好,谢谢你的帮助。我本来想发表这个评论,但是我注意到你已经先发了,所以我给了一个赞。 - user3413723

0

@Riki137的答案非常好用。 如果有人想尝试另一种方法,这里还有一个方案。

   _appBar = AppBar();
   return PreferredSize(
     child: ShaderMask(
         child: _appBar,
        shaderCallback: (rect) {
           return ui.Gradient.linear(rect.centerLeft, rect.centerRight,
               [Colors.black, Colors.grey]);
         }),
     preferredSize: _appBar.preferredSize,
  );


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接