Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 使用Painter类向容器添加自定义装饰_Flutter - Fatal编程技术网

Flutter 使用Painter类向容器添加自定义装饰

Flutter 使用Painter类向容器添加自定义装饰,flutter,Flutter,我知道我可以装饰我的容器,然后为它提供一个边框。 但是我正在尝试使用自定义绘制类用一些自定义边框来包装我的容器,自定义绘制类应该围绕或向容器提供一个边框,就像一个虚线边框或任何自定义形状边框一样 注意:-请不要建议我使用任何自定义软件包,如虚线边框,我希望答案采用自定义画师的形式,如BoxPainter类等。 到目前为止,我已经写了这个code import'dart:math'; 进口“包装:颤振/材料.省道”; 类CustPaint扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返

我知道我可以装饰我的容器,然后为它提供一个边框。 但是我正在尝试使用自定义绘制类用一些自定义边框来包装我的
容器
,自定义绘制类应该围绕或向
容器
提供一个
边框
,就像一个
虚线
边框
或任何自定义形状边框一样

注意:-请不要建议我使用任何自定义软件包,如虚线边框,我希望答案采用自定义画师的形式,如BoxPainter类等。

到目前为止,我已经写了这个
code

import'dart:math';
进口“包装:颤振/材料.省道”;
类CustPaint扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:容器(
宽度:300,
身高:300,
装饰:自定义装饰(),
孩子:新图标(Icons.wb_sunny),
)),
);
}
}
阶级装饰延伸了装饰{
@凌驾
BoxPainter createBoxPainter([void Function()onChanged]){
返回BoxDecorationPainter();
}
}
类BoxDecorationPainter扩展了BoxPainter{
@凌驾
虚空绘制(画布、偏移、图像配置){
最终矩形边界=偏移量和配置.size;
_绘画装饰(帆布、镶边);
}
}
void\u drawDecoration(帆布,矩形尺寸){
变量半径=最小值(尺寸.宽度/2,尺寸.高度/2);
var circleRaidus=半径*.012;
var paint=paint()
…color=Colors.teal
..strokeWidth=circleRaidus*.5
…风格=绘画风格笔划
..strokeCap=strokeCap.round;
对于(int i=0;i<60;i++){
偏移量topRight=偏移量(size.left+i*4,size.top);
左下偏移=偏移(size.left,size.top+i*4);
偏置底部右=偏置(size.left+i*4,size.bottom);
向下偏移=偏移(size.right,size.top+i*4);
画布。画圈(右上角,画圈*2,绘画);
画布.画圈(右下角,圆圈*2,油漆);
画布.画圈(右下,画圈*2,绘画);
画布.画圈(左下,画圈*2,绘画);
}
}
我所取得的成就是

但是输出

  • 我想要的是所有的
    (带小圆圈)都应该连接在一起,并且当遇到
    时,它们之间不应该有
    间隙
    。(意味着它们应该连接起来,像正方形或矩形一样覆盖容器)
  • 我还想在那些小的
    圆圈之间留出一些
    空间
    一些
    填充
  • 如果这些
    圆圈
    可以 替换为任何
    图像

  • 提前感谢

    必须根据盒子的大小调整圆圈的数量:

    final nbShapes = [
      ((bounds.width + gap) / (shapeSize + gap)).floor(),
      ((bounds.height + gap) / (shapeSize + gap)).floor(),
    ];
    

    在我的解决方案中,CustomDecorationBox可以配置为:

    • 双形状大小
      ,形状的大小
    • 双形状贴图
      ,两个形状之间的间隙
    • 绘制形状绘制
      ,用于绘制形状的绘制(支持笔划和填充绘制)
    • shapePAINTERPAINTSHAPE
      ,一个绘制形状的函数
    我提供了3个ShapePainter样本:

    • paintCircle()
    • paintRectangle()
    • ShapePainter创建NgoNpainter(int n)
      ,一家n-gon画家工厂

    完整源代码:

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    typedef ShapePainter = void Function(Canvas, Rect, Paint);
    
    Random random = Random();
    
    void main() {
      runApp(
        MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'CustomDecoration Demo',
          home: Scaffold(
            body: MyWidget(),
          ),
        ),
      );
    }
    
    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: LayoutBuilder(
            builder: (context, constraints) {
              final size = Size(1, .6) * constraints.biggest.width;
              print(size);
              return GridView.count(
                crossAxisCount: 3,
                children: List.generate(
                  120,
                  (index) => Padding(
                    padding: EdgeInsets.all(size.width * .01),
                    child: Container(
                      decoration: CustomDecoration(
                        shapeSize: 5.0 + random.nextInt(10),
                        shapeGap: 2.0 + random.nextInt(3),
                        shapePaint: Paint()
                          ..color = Color(0x99000000 + random.nextInt(0xffffff))
                          ..strokeWidth = random.nextInt(3).toDouble()
                          ..style = random.nextInt(3) == 2
                              ? PaintingStyle.fill
                              : PaintingStyle.stroke,
                        paintShape: random.nextInt(4) == 0
                            ? paintCircle
                            : createNGonPainter(3 + random.nextInt(5)),
                      ),
                      child: Center(
                        child: Text(
                          index.toString(),
                          style: TextStyle(fontSize: 24.0),
                        ),
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }
    }
    
    class CustomDecoration extends Decoration {
      final double shapeSize;
      final double shapeGap;
      final Paint shapePaint;
      final ShapePainter paintShape;
    
      CustomDecoration({
        this.shapeSize,
        this.shapeGap,
        this.shapePaint,
        this.paintShape,
      }) : super();
    
      @override
      BoxPainter createBoxPainter([void Function() onChanged]) {
        return BoxDecorationPainter(
            shapeSize: shapeSize ?? 10,
            shapeGap: shapeGap ?? 4,
            shapePaint: shapePaint ?? Paint(),
            paintShape: paintShape ?? paintCircle);
      }
    }
    
    class BoxDecorationPainter extends BoxPainter {
      final double shapeSize;
      final double shapeGap;
      final Paint shapePaint;
      final ShapePainter paintShape;
    
      BoxDecorationPainter({
        this.shapeSize,
        this.shapeGap,
        this.shapePaint,
        this.paintShape,
      }) : super();
    
      @override
      void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
        final Rect bounds = offset & configuration.size;
        _drawDecoration(canvas, bounds, shapeSize, shapeGap);
      }
    
      void _drawDecoration(
          Canvas canvas, Rect bounds, double shapeSize, double gap) {
        final nbShapes = [
          ((bounds.width + gap) / (shapeSize + gap)).floor(),
          ((bounds.height + gap) / (shapeSize + gap)).floor(),
        ];
        final correctedGaps = [
          (bounds.width - nbShapes[0] * shapeSize) / (nbShapes[0] - 1),
          (bounds.height - nbShapes[1] * shapeSize) / (nbShapes[1] - 1),
        ];
        final steps = [
          correctedGaps[0] + shapeSize,
          correctedGaps[1] + shapeSize,
        ];
    
        for (int i = 0; i < nbShapes[0]; i++) {
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.left + steps[0] * i,
              bounds.top,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.left + steps[0] * i,
              bounds.bottom - shapeSize,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
        }
    
        for (int i = 1; i < nbShapes[1] - 1; i++) {
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.left,
              bounds.top + steps[1] * i,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.right - shapeSize,
              bounds.top + steps[1] * i,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
        }
      }
    }
    
    void paintCircle(Canvas canvas, Rect bounds, Paint paint) {
      canvas.drawCircle(
        Offset(
          bounds.left + bounds.width / 2,
          bounds.top + bounds.height / 2,
        ),
        bounds.shortestSide / 2,
        paint,
      );
    }
    
    void paintRectangle(Canvas canvas, Rect bounds, Paint paint) {
      canvas.drawRect(bounds, paint);
    }
    
    ShapePainter createNGonPainter(int n) => (canvas, bounds, paint) {
          Path path = Path();
          path.moveTo(
            bounds.left + (bounds.width + cos(2 * pi / n) * bounds.width) / 2,
            bounds.top + (bounds.height + sin(2 * pi / n) * bounds.height) / 2,
          );
          for (var k = 2; k <= n; k++) {
            path.lineTo(
              bounds.left + (bounds.width + cos(2 * k * pi / n) * bounds.width) / 2,
              bounds.top +
                  (bounds.height + sin(2 * k * pi / n) * bounds.height) / 2,
            );
          }
          path.close();
          canvas.drawPath(path, paint);
        };
    
    import'dart:math';
    进口“包装:颤振/材料.省道”;
    typedef ShapePainter=无效函数(画布、矩形、绘制);
    随机=随机();
    void main(){
    runApp(
    材料聚丙烯(
    debugShowCheckedModeBanner:false,
    标题:“定制装饰演示”,
    家:脚手架(
    正文:MyWidget(),
    ),
    ),
    );
    }
    类MyWidget扩展了无状态Widget{
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    正文:布局生成器(
    生成器:(上下文、约束){
    最终尺寸=尺寸(1.6)*约束。最大。宽度;
    印刷品(尺寸);
    返回GridView.count(
    交叉轴计数:3,
    子项:List.generate(
    120,
    (索引)=>填充(
    填充:所有边缘设置(尺寸.宽度*.01),
    子:容器(
    装饰:定制装饰(
    形状大小:5.0+随机。下一个(10),
    shapeGap:2.0+随机。nextInt(3),
    shapePaint:Paint()
    …color=color(0x99000000+random.nextInt(0xffffff))
    ..strokeWidth=random.nextInt(3).toDouble()
    …样式=随机。下一个(3)==2
    ?油漆方式。填充
    :PaintingStyle.stroke,
    paintShape:random.nextInt(4)=0
    ?画圈
    :createNGonPainter(3+random.nextInt(5)),
    ),
    儿童:中心(
    子:文本(
    index.toString(),
    样式:TextStyle(fontSize:24.0),
    ),
    ),
    ),
    ),
    ),
    );
    },
    ),
    );
    }
    }
    阶级装饰延伸了装饰{
    最终的双形化;
    最后的双形图;
    最终油漆成型漆;
    最终形状中间油漆形状;
    定制装饰({
    这是shapeSize,
    这是shapeGap,
    这是shapePaint,
    这是我的画形,
    }):super();
    @凌驾
    BoxPainter createBoxPainter([void Function()onChanged]){
    返回框装饰油漆工(
    形状尺寸:形状尺寸±10,
    shapeGap:shapeGap?4,
    shapePaint:shapePaint??Paint(),
    paintShape:paintShape??paintCircle);
    }
    }
    箱形装饰类
    
    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    typedef ShapePainter = void Function(Canvas, Rect, Paint);
    
    Random random = Random();
    
    void main() {
      runApp(
        MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'CustomDecoration Demo',
          home: Scaffold(
            body: MyWidget(),
          ),
        ),
      );
    }
    
    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: LayoutBuilder(
            builder: (context, constraints) {
              final size = Size(1, .6) * constraints.biggest.width;
              print(size);
              return GridView.count(
                crossAxisCount: 3,
                children: List.generate(
                  120,
                  (index) => Padding(
                    padding: EdgeInsets.all(size.width * .01),
                    child: Container(
                      decoration: CustomDecoration(
                        shapeSize: 5.0 + random.nextInt(10),
                        shapeGap: 2.0 + random.nextInt(3),
                        shapePaint: Paint()
                          ..color = Color(0x99000000 + random.nextInt(0xffffff))
                          ..strokeWidth = random.nextInt(3).toDouble()
                          ..style = random.nextInt(3) == 2
                              ? PaintingStyle.fill
                              : PaintingStyle.stroke,
                        paintShape: random.nextInt(4) == 0
                            ? paintCircle
                            : createNGonPainter(3 + random.nextInt(5)),
                      ),
                      child: Center(
                        child: Text(
                          index.toString(),
                          style: TextStyle(fontSize: 24.0),
                        ),
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }
    }
    
    class CustomDecoration extends Decoration {
      final double shapeSize;
      final double shapeGap;
      final Paint shapePaint;
      final ShapePainter paintShape;
    
      CustomDecoration({
        this.shapeSize,
        this.shapeGap,
        this.shapePaint,
        this.paintShape,
      }) : super();
    
      @override
      BoxPainter createBoxPainter([void Function() onChanged]) {
        return BoxDecorationPainter(
            shapeSize: shapeSize ?? 10,
            shapeGap: shapeGap ?? 4,
            shapePaint: shapePaint ?? Paint(),
            paintShape: paintShape ?? paintCircle);
      }
    }
    
    class BoxDecorationPainter extends BoxPainter {
      final double shapeSize;
      final double shapeGap;
      final Paint shapePaint;
      final ShapePainter paintShape;
    
      BoxDecorationPainter({
        this.shapeSize,
        this.shapeGap,
        this.shapePaint,
        this.paintShape,
      }) : super();
    
      @override
      void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
        final Rect bounds = offset & configuration.size;
        _drawDecoration(canvas, bounds, shapeSize, shapeGap);
      }
    
      void _drawDecoration(
          Canvas canvas, Rect bounds, double shapeSize, double gap) {
        final nbShapes = [
          ((bounds.width + gap) / (shapeSize + gap)).floor(),
          ((bounds.height + gap) / (shapeSize + gap)).floor(),
        ];
        final correctedGaps = [
          (bounds.width - nbShapes[0] * shapeSize) / (nbShapes[0] - 1),
          (bounds.height - nbShapes[1] * shapeSize) / (nbShapes[1] - 1),
        ];
        final steps = [
          correctedGaps[0] + shapeSize,
          correctedGaps[1] + shapeSize,
        ];
    
        for (int i = 0; i < nbShapes[0]; i++) {
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.left + steps[0] * i,
              bounds.top,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.left + steps[0] * i,
              bounds.bottom - shapeSize,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
        }
    
        for (int i = 1; i < nbShapes[1] - 1; i++) {
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.left,
              bounds.top + steps[1] * i,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
          paintShape(
            canvas,
            Rect.fromLTWH(
              bounds.right - shapeSize,
              bounds.top + steps[1] * i,
              shapeSize,
              shapeSize,
            ),
            shapePaint,
          );
        }
      }
    }
    
    void paintCircle(Canvas canvas, Rect bounds, Paint paint) {
      canvas.drawCircle(
        Offset(
          bounds.left + bounds.width / 2,
          bounds.top + bounds.height / 2,
        ),
        bounds.shortestSide / 2,
        paint,
      );
    }
    
    void paintRectangle(Canvas canvas, Rect bounds, Paint paint) {
      canvas.drawRect(bounds, paint);
    }
    
    ShapePainter createNGonPainter(int n) => (canvas, bounds, paint) {
          Path path = Path();
          path.moveTo(
            bounds.left + (bounds.width + cos(2 * pi / n) * bounds.width) / 2,
            bounds.top + (bounds.height + sin(2 * pi / n) * bounds.height) / 2,
          );
          for (var k = 2; k <= n; k++) {
            path.lineTo(
              bounds.left + (bounds.width + cos(2 * k * pi / n) * bounds.width) / 2,
              bounds.top +
                  (bounds.height + sin(2 * k * pi / n) * bounds.height) / 2,
            );
          }
          path.close();
          canvas.drawPath(path, paint);
        };