简体   繁体   English

如何在颤振中绘制自定义形状的卡片

[英]How to draw a custom shape card in flutter

I just want to create card like this我只想创建这样的卡片

在此处输入图片说明

The code is as follows, I used the CustomPaint Widget to draw the custom shape and then used stack inside the Card Widget to place the widgets correctly.代码如下,我使用CustomPaint Widget 绘制自定义形状,然后使用Card Widget 内部的 stack 正确放置小部件。

I did not the Image so changed it with a pink colour to show the image:我没有图像所以用粉红色更改它以显示图像:


Here is the Code for the Card Widget then followed bu it is the CustomPainter class:这是 Card Widget 的代码,然后是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,
                ),
              ),
            ],
          ),
        ),
      ),

Custom Painter Class:自定义画家类:

/// 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: The grey container is used to depict the contents inside Custom Shape OutPut:灰色容器用于描绘Custom Shape里面的内容

输出图像

The Whole Code:整个代码:

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

The output screen I hope this is helpful.输出屏幕我希望这是有帮助的。 The code:编码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM