Lao Meng's introduction : Many components in Flutter have a
shape
property called , the type isShapeBorder
, such as Button class, Card and other components,shape
representing the shape of the control. The system has provided us with many shapes. For components without this property, you can use Clip Class components are cut.
BeveledRectangleBorder
Bevel rectangular border, usage is as follows:
RaisedButton(
shape: BeveledRectangleBorder(
side: BorderSide(width: 1, color: Colors.red),
borderRadius: BorderRadius.circular(10)),
child: Text('老孟'),
onPressed: () {},
)
If you set a radius larger than the control, it will become a diamond :
3RaisedButton(
shape: BeveledRectangleBorder(
side: BorderSide(width: 1, color: Colors.red),
borderRadius: BorderRadius.circular(100)),
child: Text('老孟'),
onPressed: () {},
)
Similarly, if the radius is set to 0, it is a rectangle.
RaisedButton(
shape: BeveledRectangleBorder(
side: BorderSide(width: 1, color: Colors.red),
borderRadius: BorderRadius.circular(0)),
child: Text('老孟'),
onPressed: () {},
)
Border
Border allows the line style on each side to be individually set.
RaisedButton(
shape: Border(
top: BorderSide(color: Colors.red,width: 2)
),
child: Text('老孟'),
onPressed: () {},
)
Set all
RaisedButton(
shape: Border(
top: BorderSide(color: Colors.red,width: 10),
right: BorderSide(color: Colors.blue,width: 10),
bottom: BorderSide(color: Colors.yellow,width: 10),
left: BorderSide(color: Colors.green,width: 10),
),
child: Text('老孟'),
onPressed: () {},
)
BorderDirectional
BorderDirectional and Border essentially the same, the difference is BorderDirectional with reading direction, reading from left to right in most countries, but some countries are right to left, such as Arabic and so on.
RaisedButton(
shape: BorderDirectional(
start: BorderSide(color: Colors.red,width: 2),
end: BorderSide(color: Colors.blue,width: 2),
),
child: Text('老孟'),
onPressed: () {},
)
CircleBorder
Round
RaisedButton(
shape: CircleBorder(side: BorderSide(color: Colors.red)),
child: Text('老孟'),
onPressed: () {},
)
ContinuousRectangleBorder
A continuous rounded rectangle, a smooth and continuous transition between straight lines and rounded corners, has a smaller rounded corner effect compared to RoundedRectangleBorder.
RaisedButton(
shape: ContinuousRectangleBorder(
side: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(20)),
child: Text('老孟'),
onPressed: () {},
)
RoundedRectangleBorder
Rounded Rectangle
RaisedButton(
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(10)),
child: Text('老孟'),
onPressed: () {},
)
StadiumBorder
Similar to the shape of a football field , round on both sides, rectangular in the middle
RaisedButton(
shape: StadiumBorder(
side: BorderSide(color: Colors.red),),
child: Text('老孟'),
onPressed: () {},
)
OutlineInputBorder
With outer border
RaisedButton(
shape: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(10),
),
child: Text('老孟'),
onPressed: () {},
)
UnderlineInputBorder
Underline border
RaisedButton(
shape: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
child: Text('老孟'),
onPressed: () {},
)
ClipRect
ClipRect rectangular cropping assembly subassembly, usually, clipRect acting CustomPaint
, CustomSingleChildLayout
, CustomMultiChildLayout
, Align
, Center
, OverflowBox
, SizedOverflowBox
components such as the Align clipRect acts on, only the upper half portion may be displayed, as follows:
ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: Container(
height: 150,
width: 150,
child: Image.asset(
'images/1.png',
fit: BoxFit.cover,
),
),
),
)
Full image effect:
Cutting effect:
clipper
The parameters define the cutting rules, which are described in detail below.
clipBehavior
The parameter defines the cutting method. Only the child control is beyond the scope of the parent control can be cut. Each method is explained as follows:
- none: No clipping, the system default value. If the subcomponent does not exceed the boundary, this value has no performance consumption.
- hardEdge: Crop without applying anti-aliasing, which is
none
slower than other methods, but faster than other methods. - antiAlias: cropping and anti-aliasing, this method looks smoother,
antiAliasWithSaveLayer
faster thanhardEdge
slower, usually used to handle circular and arc-shaped cropping. - antiAliasWithSaveLayer: cropping, anti-aliasing, and a buffer. This method is very slow and is rarely used.
ClipRRect
The ClipRRect component can round corners of the sub-components. The default corner radius is 0. Note that ClipRRect has 2 Rs, not the ClipRect described above.
The usage is as follows:
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Container(
height: 150,
width: 150,
child: Image.asset(
'images/1.png',
fit: BoxFit.cover,
),
),
)
The effect is as follows:
ClipOval
ClipOval is cut into an ellipse, and the size of the ellipse is tangent to the parent component, so if the parent component is square, the cut out is a circle. The usage is as follows:
ClipOval(
child: Container(
height: 150,
width: 250,
child: Image.asset(
'images/1.png',
fit: BoxFit.cover,
),
),
)
The effect is as follows:
ClipPath
The ClipPath component cuts according to the path. We can also use the custom clipping path provided by the system. The usage is as follows:
ClipPath.shape(
shape: StadiumBorder(),
child: Container(
height: 150,
width: 250,
child: Image.asset(
'images/1.png',
fit: BoxFit.cover,
),
),
)
shape
The parameter is of the ShapeBorder type. The system has defined many shapes. The introduction is as follows:
RoundedRectangleBorder: rounded rectangle
ContinuousRectangleBorder: A smooth and continuous transition between straight lines and rounded corners. Compared with RoundedRectangleBorder, the rounded corners have a smaller effect.
StadiumBorder: Similar to the shape of a football field, with semicircles at both ends.
BeveledRectangleBorder: Beveled rectangle. The effect is as follows:
CircleBorder: Circle.
CustomClipper
CustomClipper is not a component, but an abstract
(abstract) class. Using CustomClipper, we can draw any shape we want, such as a triangle. The code is as follows:
@override
Widget build(BuildContext context) {
return Center(
child: ClipPath(
clipper: TrianglePath(),
child: Container(
height: 150,
width: 250,
child: Image.asset(
'images/1.png',
fit: BoxFit.cover,
),
),
),
);
}
The custom TrianglePath code is as follows:
class TrianglePath extends CustomClipper<Path>{
@override
Path getClip(Size size) {
var path = Path();
path.moveTo(size.width/2, 0);
path.lineTo(0, size.height);
path.lineTo(size.width, size.height);
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
The effect is as follows:
We can also draw a five-pointed star, the code is as follows:
class StarPath extends CustomClipper<Path> {
StarPath({this.scale = 2.5});
final double scale;
double perDegree = 36;
/// 角度转弧度公式
double degree2Radian(double degree) {
return (pi * degree / 180);
}
@override
Path getClip(Size size) {
var R = min(size.width / 2, size.height / 2);
var r = R / scale;
var x = size.width / 2;
var y = size.height / 2;
var path = Path();
path.moveTo(x, y - R);
path.lineTo(x - sin(degree2Radian(perDegree)) * r,
y - cos(degree2Radian(perDegree)) * r);
path.lineTo(x - sin(degree2Radian(perDegree * 2)) * R,
y - cos(degree2Radian(perDegree * 2)) * R);
path.lineTo(x - sin(degree2Radian(perDegree * 3)) * r,
y - cos(degree2Radian(perDegree * 3)) * r);
path.lineTo(x - sin(degree2Radian(perDegree * 4)) * R,
y - cos(degree2Radian(perDegree * 4)) * R);
path.lineTo(x - sin(degree2Radian(perDegree * 5)) * r,
y - cos(degree2Radian(perDegree * 5)) * r);
path.lineTo(x - sin(degree2Radian(perDegree * 6)) * R,
y - cos(degree2Radian(perDegree * 6)) * R);
path.lineTo(x - sin(degree2Radian(perDegree * 7)) * r,
y - cos(degree2Radian(perDegree * 7)) * r);
path.lineTo(x - sin(degree2Radian(perDegree * 8)) * R,
y - cos(degree2Radian(perDegree * 8)) * R);
path.lineTo(x - sin(degree2Radian(perDegree * 9)) * r,
y - cos(degree2Radian(perDegree * 9)) * r);
path.lineTo(x - sin(degree2Radian(perDegree * 10)) * R,
y - cos(degree2Radian(perDegree * 10)) * R);
return path;
}
@override
bool shouldReclip(StarPath oldClipper) {
return oldClipper.scale != this.scale;
}
}
scale
The parameter represents the zoom ratio from the point of the interval to the center of the circle. The effect of the five-pointed star is as follows:
The following is dynamically set with animation scale
, the code is as follows:
class StartClip extends StatefulWidget {
@override
State<StatefulWidget> createState() => _StartClipState();
}
class _StartClipState extends State<StartClip>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation _animation;
@override
void initState() {
_controller =
AnimationController(duration: Duration(seconds: 2), vsync: this)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.reverse();
} else if (status == AnimationStatus.dismissed) {
_controller.forward();
}
});
_animation = Tween(begin: 1.0, end: 4.0).animate(_controller);
_controller.forward();
super.initState();
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return ClipPath(
clipper: StarPath(scale: _animation.value),
child: Container(
height: 150,
width: 150,
color: Colors.red,
),
);
}),
);
}
}
The effect is as follows:
communicate with
Laomeng Flutter blog address (330 control usage): http://laomengit.com
Welcome to join the Flutter exchange group (WeChat: laomengit) and follow the public account [Lao Meng Flutter]: