Reputation: 193
I'm trying to build a background consisting of alternating red and orange stripes like this:
I don't want to use a static image to ensure consistency over different devices.
I tried to use gradients but I'm having trouble making it work.
Container(
decoration: BoxDecoration(
// Box decoration takes a gradient
gradient: LinearGradient(
// Where the linear gradient begins and ends
begin: Alignment.topRight,
end: Alignment(0.3, 0),
tileMode: TileMode.repeated, // repeats the gradient over the canvas
colors: [
// Colors are easy thanks to Flutter's Colors class.
Colors.red,
Colors.orange,
],
),
),
),
Is there a better way to solve this other than gradients in Dart / Flutter?
Upvotes: 13
Views: 10803
Reputation: 1887
I've just modified gradient value in the question and ended up with this.
You can adjust the end
value to change the angle and width of the strips.
BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment(-0.4, -0.8),
stops: [0.0, 0.5, 0.5, 1],
colors: [
Colors.red,
Colors.red,
Colors.orange,
Colors.orange,
],
tileMode: TileMode.repeated,
),
)
Link to LinearGradient Documentation
Link to Alignment Documentation
Upvotes: 38
Reputation: 854
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: CustomPaint(
size: Size(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height),
painter: BackGround(),
child: Container(
child: Center(
child: Icon(Icons.android , size: 100,),
),
),
),
),
backgroundColor: Colors.black,
);
}
}
class BackGround extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = Colors.red;
paint.strokeWidth = 100;
paint.isAntiAlias = true;
Paint paint2 = new Paint();
paint2.color = Colors.orange;
paint2.strokeWidth = 100;
paint2.isAntiAlias = true;
canvas.drawLine(Offset(300, -120), Offset(size.width+60, size.width-280), paint2);
canvas.drawLine(Offset(200, -80), Offset(size.width+60, size.width-160), paint);
canvas.drawLine(Offset(100, -40), Offset(size.width+60, size.width-40), paint2);
canvas.drawLine(Offset(0, 0), Offset(size.width+60, size.width+80), paint);
canvas.drawLine(Offset(-100, 40), Offset(size.width+60, size.width+200), paint2);
canvas.drawLine(Offset(-200, 90), Offset(size.width+60, size.width+320), paint);
canvas.drawLine(Offset(-300, 140), Offset(size.width+60, size.width+440), paint2);
canvas.drawLine(Offset(-400, 190), Offset(size.width+60, size.width+560), paint);
canvas.drawLine(Offset(-500, 240), Offset(size.width+60, size.width+680), paint2);
}
Upvotes: 1
Reputation: 1759
What about using Clipper and using stack of RectangularWidgets and clipping off the left corner triangle each time with increasing heights.
class MyCustomClipper extends CustomClipper<Path> {
final double extent;
MyCustomClipper({this.extent});
@override
Path getClip(Size size) {
var path = Path();
path.moveTo(0, extent);
path.lineTo(extent, 0);
path.lineTo(size.width, 0);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
class StripsWidget extends StatelessWidget {
final Color color1;
final Color color2;
final double gap;
final noOfStrips;
const StripsWidget(
{Key key, this.color1, this.color2, this.gap, this.noOfStrips})
: super(key: key);
List<Widget> getListOfStripes() {
List<Widget> stripes = [];
for (var i = 0; i < noOfStrips; i++) {
stripes.add(
ClipPath(
child: Container(color: (i%2==0)?color1:color2),
clipper: MyCustomClipper(extent: i*gap),
),
);
}
return stripes;
}
@override
Widget build(BuildContext context) {
return Stack(children: getListOfStripes());
}
}
StripsWidget(
color1:Color.fromRGBO(231, 79, 36, 1),
color2:Color.fromRGBO(218, 59, 32, 1),
gap: 100,
noOfStrips: 10,
),
At each time I clipped top left triangle and increased the size of triangle with gap of specified gap in constructor and ran loop noOfStrips times in the constructor defined.
And the output that I got was exactly the same
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:StripsWidget(color1:Color.fromRGBO(231, 79, 36, 1),color2:Color.fromRGBO(218, 59, 32, 1),gap: 100,noOfStrips: 10,),
);
}
}
Upvotes: 2
Reputation: 16187
Use canvas (CustomPainter and CustomPaint Widgets).
Or SVG by package: https://pub.dev/packages/flutter_svg
Upvotes: 0