In previous articles, we introduced Dart’s two compile-times, as well as the Hot Reload mode. Today we will look at how to create irregular widgets in Flutter. In Android, we create an irregular boundary View using clipPath. There are also related concepts in Flutter. Let’s learn about clipPath in Flutter and its usage.

ClipPath Widget

Everything is Widget in Flutter. If you want to use Path, the Widget object is ClipPath.

ClipPath Extends Map

The inheritance relationship of ClipPath Widget is shown below:

enter image description here

ClipPath Introduce

ClipPath is described in the official documentation as follows:

A widget that clips its child using a path.

There are three properties associated with ClipPath:

  • Child:WidgetType, croppedWidgetobject
  • Clipper: Defines the clipping pathCustomClipperObject that internally provides a clipping path and whether it needs to be clipped again
  • ClipBehavior: cuttingWidgetThe default value isClip.antiAlias, and the optional values areClip.none.Clip.hardEdge.Clip.antiAlias.Clip.antiAliasWithSaveLayer.

The difference between clipping mode values is as follows:

  • None: Indicates no mode
  • HardEdge: Slightly faster clipping speed, but easy to distort, serrated
  • AntiAlias: Clipping edge anti-aliasing, making clipping smoother than this mode clipping speedantiAliasWithSaveLayerFast, but fasterhardEdgeSlow, this mode is often used for shapes like circles and arcs
  • AntiAliasWithSaveLayer: Clipping has anti-aliasing features and allocates screen buffers, all subsequent operations are performed in buffers, then clipping and compositing

ClipPath Use

In code we can declare a ClipPath Widget using the following code,

1ClipPath(
2      child: Image.asset('images/coffee.jpg'),// Clipping Widget object, here is an Image Widget 3 clipper: BottomWaveClipper(),// clipping path 4)Copy the code

BottomWaveClipper defines the clipping path of the Image Widget, which is a subclass of CustomClipper. The code is as follows:

1class BottomWaveClipper extends CustomClipper<Path>{ 2 3 @override 4 Path getClip(Size size) { 5 var path = Path(); 6 path. LineTo (0.0, the size height - 20); 9 var firstControlPoint = Offset(sie.width /4, sie.height); 11 var firstEndPoint = Offset(sie.width /2.25, sie.height-30); 12 path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstEndPoint.dx, firstEndPoint.dy); 15 var secondControlPoint = Offset(sie.width - (sie.width / 3.25), sie.height - 65); 17 var secondEndPoint = Offset(sie.width, sie.height-40); 18 path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy, 19 secondEndPoint.dx, secondEndPoint.dy); 20 21 path.lineTo(size.width, size.height - 40); 22 path. LineTo (size, width, 0.0); 23 path.close(); 24returnpath; 27} 27 @override 28 bool shouldReclip(CustomClipper<Path> oldClipper) {29 // whether to reset 30return false; 31} 32}Copy the code

The cropped Image Widget built with the above code is as follows:

enter image description here

The complete code for the WavyHeaderImage Widget is as follows:


 1import 'package:flutter/material.dart';
 2
 3class WavyHeaderImage extends StatelessWidget {
 4
 5  @override
 6  Widget build(BuildContext context) {
 7    return ClipPath(
 8      child: Image.asset('images/coffee.jpg'), 9 clipper: BottomWaveClipper(), 10 ); 11 } 12} 13 14class BottomWaveClipper extends CustomClipper<Path>{ 15 16 @override 17 Path getClip(Size size) { 18 var path = Path(); 19 path. The lineTo (0.0, the size height - 20); 20 21 var firstControlPoint = Offset(size.width/4, size.height); 22 var firstEndPoint = Offset(sie.width /2.25, sie.height-30); 23 path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstEndPoint.dx, firstEndPoint.dy); 24 25 var secondControlPoint = Offset(sie.width - (sie.width / 3.25), sie.height - 65); 26 var secondEndPoint = Offset(size.width, size.height - 40); 27 path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy, 28 secondEndPoint.dx, secondEndPoint.dy); 29 30 path.lineTo(size.width, size.height - 40); 31 path. LineTo (size, width, 0.0); 32 path.close(); 33return path;
34  }
35
36  @override
37  bool shouldReclip(CustomClipper<Path> oldClipper) {
38    return false; 39}} 40Copy the code

1  @override
2  Widget build(BuildContext context) {
3    returnnew Scaffold( 4 backgroundColor: Colors.blueGrey, 5 body: WavyHeaderImage(), 6 ); 7}Copy the code

Personal wechat public account, welcome to join.

enter image description here