How to use ClipPath Flutter

寵の児 提交于 2021-02-10 23:19:12

问题


I want to give the above background for container, tried the following code.but it's not working

ClipPath(
            clipper: TriangleClipper(),
            child: Container(
                margin: EdgeInsets.only(top: 20, right: 20),
                padding: EdgeInsets.all(20),
                decoration: BoxDecoration(
                    color: cardBackground,
                    borderRadius: BorderRadius.circular(10))),


    Class TriangleClipper extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        final path = Path();
        path.lineTo(0.0, size.height);
        path.lineTo(size.width, size.height);
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(TriangleClipper oldClipper) => false;
    }

回答1:


It's better to use custom shapes for this kind of purposes..

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(18.0),
            child: Container(
              decoration: ShapeDecoration(
                color: Color(0xFFf3effd),
                shape: MyBorderShape(),
                shadows: [
                  BoxShadow(
                      color: Colors.black38,
                      blurRadius: 8.0,
                      offset: Offset(1, 1)),
                ],
              ),
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

class MyBorderShape extends ShapeBorder {
  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.zero;

  @override
  Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;

  final double holeSize = 70;
  final double borderRadius = 10;

  @override
  Path getOuterPath(Rect rect, {TextDirection textDirection}) {
    print(rect.topLeft);
    var startX = rect.topLeft.dx;
    var startY = rect.topLeft.dy;

    return Path.combine(
      PathOperation.union,
      Path()
        ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(borderRadius)))
        ..close(),
      Path()
        ..moveTo(startX + 20, startY)
        ..lineTo(startX + 35, startY - 15)
        ..lineTo(startX + 50, startY)
        ..close(),
    );
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {}

  @override
  ShapeBorder scale(double t) => this;
}



回答2:


With ClipPath, you need to draw the entire path which you want to carve, which will include drawing the triangle as well as the top-left and top-right rounded corners, because the corresponding original corners (borderRadius: BorderRadius.circular(10)) will be cropped out. One way you can do this is something like this.

class _MyWidgetState extends State<MyWidget> {

  @override
  Widget build(BuildContext context) {
    return ClipPath(
      clipper: TriangleClipper(),
      child: Container(
        padding: EdgeInsets.fromLTRB(20, 30, 20, 20),   //extra 10 for top padding because triangle's height = 10
        decoration: BoxDecoration(
          color: Colors.green,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Text('My parent is a fancy container'),
      ),
    );
  }
}


class TriangleClipper extends CustomClipper<Path> {
  
  double radius = 10, tw = 20, th = 10;      //tw & th = triangle width & height
  
  @override
  Path getClip(Size size) {
    final path = Path();
    path.lineTo(0, size.height);
    path.lineTo(size.width, size.height);
    path.lineTo(size.width, th + radius);
    path.arcToPoint(Offset(size.width - radius, th), radius: Radius.circular(radius), clockwise: false);
    path.lineTo(radius + 10 + tw, th);
    path.lineTo(radius + 10 + tw/2, 0);      //in these lines, the 10 is to have a space of 10 between the top-left corner curve and the triangle
    path.lineTo(radius + 10, th);
    path.lineTo(radius, th);
    path.arcToPoint(Offset(0, th + radius), radius: Radius.circular(radius), clockwise: false);
    return path;
  }

  @override
  bool shouldReclip(TriangleClipper oldClipper) => false;
}

Result:



来源:https://stackoverflow.com/questions/63448648/how-to-use-clippath-flutter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!