如何在 Flutter 中创建带条纹的背景

How to create a background with stripes in Flutter

我正在尝试构建一个由交替的红色和橙色条纹组成的背景,如下所示:

我不想使用静态图像来确保在不同设备上的一致性。

我尝试使用渐变,但我无法让它发挥作用。

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

除了 Dart / Flutter 中的渐变之外,还有更好的方法来解决这个问题吗?

使用 canvas(CustomPainter 和 CustomPaint 小部件)。

或 SVG 包:https://pub.dev/packages/flutter_svg

使用 Clipper 和使用 RectangularWidgets 堆栈,每次随着高度的增加剪掉左角三角形怎么样?

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

每次我剪裁左上角的三角形并增加三角形的大小,在构造函数中指定间隙的间隙和运行在构造函数中循环noOfStrips次定义。

我得到的输出完全一样

用法示例

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

创建自定义画图

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

我刚刚修改了问题中的梯度值,结果是这样的。 您可以调整 end 值以更改条带的角度和宽度。

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