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

问题描述

我只想创建这样的卡片

enter image description here

解决方法

代码如下,我使用CustomPaint小部件绘制自定义形状,然后使用Card小部件内部的堆栈正确放置小部件。

我没有将图片更改为粉红色来显示图片:


这是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,],

自定义Painter类:

/// 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,1);
    path.lineTo(width - radius,-height);
    path.conicTo(width,width,-(height + radius),1);
    path.lineTo(width,-(height - radius));
    path.lineTo(width,-radius);

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

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

输出: 灰色容器用于描绘“自定义形状”中的内容

Output Image

整个代码:

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)),child: Container(
                  width: 300.0,child: Stack(
                    alignment: Alignment.bottomCenter,children: [
                      // This will hold the Image in the back ground:
                      Container(
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(50.0),// This is the Custom Shape Container
                      Positioned(
                        bottom: 0.0,child: Container(
                          color: Colors.red,child: CustomPaint(
                            painter: CustomContainerShapeBorder(
                              height: 100.0,// This Holds the Widgets Inside the the custom Container;
                      Positioned(
                        bottom: 10.0,child: Container(
                          height: 80.0,));
      }
    }
    
    /// 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,});
      @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,1);
        path.lineTo(width - radius,-height);
        path.conicTo(width,1);
        path.lineTo(width,-(height - radius));
        path.lineTo(width,-radius);
    
        path.conicTo(width,1);
        path.lineTo(radius,0.0);
        path.conicTo(0.0,1);
        path.close();
        canvas.drawPath(path,Paint()..color = fillColor);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return true;
      }
    }
,

The output screen我希望这会有所帮助。 代码:

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