1

我只想创建这样的卡片

在此处输入图像描述

4

3 回答 3

4

代码如下,我使用CustomPaintWidget 来绘制自定义形状,然后在CardWidget 内部使用 stack 来正确放置小部件。

我没有图像所以用粉红色更改它以显示图像:


这是卡片小部件的代码,然后是CustomPainter类:

   Card(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(50.0)),
        elevation: 10.0,
        child: Container(
          width: 300.0,
          height: 400.0,
          child: Stack(
            alignment: Alignment.bottomCenter,
            children: [
              // This will hold the Image in the back ground:
              Container(
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(50.0),
                    color: Colors.pink[100]),
              ),
              // This is the Custom Shape Container
              Positioned(
                bottom: 0.0,
                left: 0.0,
                child: Container(
                  color: Colors.red,
                  child: CustomPaint(
                    painter: CustomContainerShapeBorder(
                      height: 100.0,
                      width: 300.0,
                      radius: 50.0,
                    ),
                  ),
                ),
              ),
              // This Holds the Widgets Inside the the custom Container;
              Positioned(
                bottom: 10.0,
                child: Container(
                  height: 80.0,
                  width: 260.0,
                  color: Colors.grey.withOpacity(0.6),
                  child: null,
                ),
              ),
            ],
          ),
        ),
      ),

自定义画家类:

/// The {CustomContainerShapeBorder} should be reactibe with different sizes,
/// If it isn't then chamge the offset values.
class CustomContainerShapeBorder extends CustomPainter {
  final double height;
  final double width;
  final Color fillColor;
  final double radius;

  CustomContainerShapeBorder({
    this.height: 400.0,
    this.width: 300.0,
    this.fillColor: Colors.white,
    this.radius: 50.0,
  });
  @override
  void paint(Canvas canvas, Size size) {
    Path path = new Path();
    path.moveTo(0.0, -radius);
    path.lineTo(0.0, -(height - radius));
    path.conicTo(0.0, -height, radius, -height, 1);
    path.lineTo(width - radius, -height);
    path.conicTo(width, -height, width, -(height + radius), 1);
    path.lineTo(width, -(height - radius));
    path.lineTo(width, -radius);

    path.conicTo(width, 0.0, width - radius, 0.0, 1);
    path.lineTo(radius, 0.0);
    path.conicTo(0.0, 0.0, 0.0, -radius, 1);
    path.close();
    canvas.drawPath(path, Paint()..color = fillColor);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

OutPut:灰色容器用于描述自定义形状内的内容

输出图像

整个代码:

import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Custom Card Design',
          theme: ThemeData(
            primarySwatch: Colors.amber,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Container(
            color: Colors.amber,
            child: Center(
              child: Card(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(50.0)),
                elevation: 10.0,
                child: Container(
                  width: 300.0,
                  height: 400.0,
                  child: Stack(
                    alignment: Alignment.bottomCenter,
                    children: [
                      // This will hold the Image in the back ground:
                      Container(
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(50.0),
                            color: Colors.pink[100]),
                      ),
                      // This is the Custom Shape Container
                      Positioned(
                        bottom: 0.0,
                        left: 0.0,
                        child: Container(
                          color: Colors.red,
                          child: CustomPaint(
                            painter: CustomContainerShapeBorder(
                              height: 100.0,
                              width: 300.0,
                              radius: 50.0,
                            ),
                          ),
                        ),
                      ),
                      // This Holds the Widgets Inside the the custom Container;
                      Positioned(
                        bottom: 10.0,
                        child: Container(
                          height: 80.0,
                          width: 260.0,
                          color: Colors.grey.withOpacity(0.6),
                          child: null,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ));
      }
    }
    
    /// The {CustomContainerShapeBorder} should be reactibe with different sizes,
    /// If it isn't then chamge the offset values.
    class CustomContainerShapeBorder extends CustomPainter {
      final double height;
      final double width;
      final Color fillColor;
      final double radius;
    
      CustomContainerShapeBorder({
        this.height: 400.0,
        this.width: 300.0,
        this.fillColor: Colors.white,
        this.radius: 50.0,
      });
      @override
      void paint(Canvas canvas, Size size) {
        Path path = new Path();
        path.moveTo(0.0, -radius);
        path.lineTo(0.0, -(height - radius));
        path.conicTo(0.0, -height, radius, -height, 1);
        path.lineTo(width - radius, -height);
        path.conicTo(width, -height, width, -(height + radius), 1);
        path.lineTo(width, -(height - radius));
        path.lineTo(width, -radius);
    
        path.conicTo(width, 0.0, width - radius, 0.0, 1);
        path.lineTo(radius, 0.0);
        path.conicTo(0.0, 0.0, 0.0, -radius, 1);
        path.close();
        canvas.drawPath(path, Paint()..color = fillColor);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return true;
      }
    }
于 2020-09-05T10:50:55.117 回答
1

我希望这对输出屏幕有所帮助。编码:

import 'package:flutter/material.dart';

main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Drawing Paths',
      home: Container(
        color: Colors.white,
        child: CustomPaint(
          painter: CurvePainter(),
        ),
      ),
    );
  }
}

class CurvePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint();
    paint.color = Colors.blueAccent;
    paint.style = PaintingStyle.fill;

    var path = Path();

    path.moveTo(size.width, size.height * 0.7);
    path.quadraticBezierTo(size.width * 0.99, size.height * 0.79,
        size.width * 0.8, size.height * 0.8);
    path.lineTo(size.width * 0.08, size.height * 0.8);
    path.quadraticBezierTo(size.width * 0.001, size.height * 0.81,
        0, size.height * 0.86);
    path.lineTo(0, size.height * 0.95);
    path.quadraticBezierTo(size.width * 0.001 , size.height * 0.98,
        size.width * 0.08, size.height * 0.99);
    path.lineTo(size.width * 0.8, size.height * 0.99);
    path.quadraticBezierTo(size.width * 0.99, size.height * 0.99,
        size.width, size.height * 0.89);
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
于 2020-09-05T13:10:54.663 回答
-1

对于任何类型的定制设计,您都可以使用此工具创建https://shapemaker.web.app/#/

于 2021-09-20T13:14:11.170 回答