MietieMn
MietieMn

Reputation: 711

Gradient Background on Flutter AppBar

How do I set the backgroundColor of theAppBar to a gradient?

Upvotes: 66

Views: 103437

Answers (7)

Wai Han Ko
Wai Han Ko

Reputation: 1043

You can decorate using 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
            ])          
         ),        
     ),      
 ),

Upvotes: 4

chornbe
chornbe

Reputation: 1164

Set the background and shadow colors to Colors.transparent in a standard AppBar, then wrap a Container(...) around it, using BoxDecoration(gradient: LinearGradient(...)), and bob is, of course, your uncle.

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

Forgive my use of undefined (in this post) constants; this was pulled from a production app and the names were changed to protect the innocent.

Screen cap showing gradient in app bar

Upvotes: 1

mirxtrem apps
mirxtrem apps

Reputation: 67

Just wrap AppBar in the Widgets Material > Container with grandient, so you can keep the original AppBar's attributes. here is my implementation with necesary attributes.

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

then, just use it wherever you want

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

Upvotes: 3

Jagraj Singh
Jagraj Singh

Reputation: 4391

@Riki137 answer work like charm. Here's another approach if anyone wanna give it a try.

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

Upvotes: 0

Riki137
Riki137

Reputation: 2521

This should work flawlessly:

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

Upvotes: 87

Mans
Mans

Reputation: 3261

I don't believe you can pass a gradient to an AppBar as it expects a Color rather than a gradient.

You can, however, create your own widget that mimics an AppBar except by using a gradient. Take a look at this example that I've pieced together from the Planets-Flutter tutorial along with the code below it.

enter image description here

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

Hope this helps. Let me know if you have any questions.

Upvotes: 54

Arnold Parge
Arnold Parge

Reputation: 6867

AppBar does not have that feature by default. But you can make an AppBar like widget which will have a gradient background as follow:

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

Here boxShadow will give elevated feel.

Upvotes: 17

Related Questions