How to create a background with stripes in Flutter

5,808

Solution 1

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

Solution 2

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

Solution 3

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);
  }
Share:
5,808
Kevin Bos
Author by

Kevin Bos

Updated on December 13, 2022

Comments

  • Kevin Bos
    Kevin Bos over 1 year

    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?