Reputation: 398
How to draw custom shape for the appBar
in my application to look like the image?
Upvotes: 7
Views: 10749
Reputation: 1
I agree with the other answers that trying to do this on the appBar itself isn't the most straightforward. Here is how I managed to accomplish the effect:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xff565992), // Match this colour to your top Container
title: Text('Title'),
),
body: Container(
decoration: BoxDecoration(
color: Color(0xff565992), // Match this colour to your appBar
),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Color(0xfffbf8ff), // This is the colour you want your body to be
borderRadius: BorderRadius.only(topLeft: Radius.circular(30), topRight: Radius.circular(30)),
),
child: <Widgets> // Start building your body from here as you would normally
)
)
);
}
Basically, I used two Containers to give the appearance that the appBar curved downwards. By matching the background colour of the top-level container and the appBar, you can't tell that it's actually the container you are seeing in the space revealed by the rounded corners of the second-level container. Then it's as simple as rounding the corners of the second-level container and making it's background colour the colour you actually want your body to be. Then you just treat it's child as if it was the beginning of the body.
The other important thing to note is that anything that scrolls will clip beyond the rounded corners at the top. There are two ways really to get around this:
padding: EdgeInsets.only(top: 10)
. This method doesn't impact performance, but it doesn't look as good because the contents will clip out at a set point within the container, instead of at it's edge.clipBehavior: Clip.antiAlias
. This could theoretically impact performance if you used it a ton, but I have never seen a noticeable impact.Upvotes: 0
Reputation: 945
As answer above. It is not part of the appbar programatically. Here is how I do it.
Create a class as such:
import 'dart:ui';
import 'package:flutter/material.dart';
class AppBarPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint_1 = Paint()
..color = const Color(0xffF57752)
..style = PaintingStyle.fill;
Path path_1 = Path()
..moveTo(0, 0)
..lineTo(size.width * .08, 0.0)
..cubicTo(
size.width * 0.04, 0.0, //x1,y1
0.0, 0.04, //x2,y2
0.0, 0.1 * size.width //x3,y3
);
Path path_2 = Path()
..moveTo(size.width, 0)
..lineTo(size.width * .92, 0.0)
..cubicTo(
size.width * .96, 0.0, //x1,y1
size.width, 0.96, //x2,y2
size.width, 0.1 * size.width //x3,y3
);
Paint paint_2 = Paint()
..color = const Color(0xffF57752)
..strokeWidth = 1
..style = PaintingStyle.stroke;
Path path_3 = Path()
..moveTo(0, 0)
..lineTo(size.width, 0);
canvas.drawPath(path_1, paint_1);
canvas.drawPath(path_2, paint_1);
canvas.drawPath(path_3, paint_2);
}
And then use it in your screen by stacking it ontop of body widget.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 80.0,
backgroundColor: const Color(0xffF57752),
elevation: 0.0,
title: const Text('Title'),
),
body: Stack(
children: [
Container(
color: Colors.white,
child: Text(' text here'),
),
CustomPaint(
painter: AppBarPainter(),
child: Container(height: 0),
),
],
),
);
}
Upvotes: 1
Reputation: 55
I built something similar with a CustomScrollView and SliverPersistenHeader, to get the curved effect your header can have a maxExtent and minExtent. When not scrolled the header height will show the curve otherwise when you start scrolling it will also shrink to a set height.
You can check out this tutorial from around 2:50 to get an idea of how to implement the header and then design your background containers accordingly.
Upvotes: 1
Reputation: 1628
I think it is not the appBar
's shape.
I think it's the white container below the green-colored appBar
that has the rounded corner.
Here's the example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlueAccent,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.only(
top: 60.0, left: 30.0, right: 30.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Hello',
style: TextStyle(
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.w700,
),
),
],
),
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
),
),
],
),
);
}
}
Upvotes: 3