Kevin Bos
Kevin Bos

Reputation: 193

How to create a background with stripes in Flutter

I'm trying to build a background consisting of alternating red and orange stripes like this: Flutter background

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

Flutter code

Is there a better way to solve this other than gradients in Dart / Flutter?

Upvotes: 13

Views: 10803

Answers (4)

ruwan800
ruwan800

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.

Image of resulting widget with red and orange repeated 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

Junsu Cho
Junsu Cho

Reputation: 854

create CustomPaintenter image description here

  @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

Nimish Bansal
Nimish Bansal

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

Usage:

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

Example Usage

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

Kherel
Kherel

Reputation: 16187

Use canvas (CustomPainter and CustomPaint Widgets).

Or SVG by package: https://pub.dev/packages/flutter_svg

Upvotes: 0

Related Questions