flutter实现四角边框
利用canvas
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
enum ThreadStrokeType {
round,
butt,
square,
}
class FourCornerFrame extends StatelessWidget {
const FourCornerFrame(
{super.key,
required this.frameWidth,
required this.frameHight,
required this.childs,
this.threadWidth = 2,
this.frameLength = 100,
this.cornerDistance = 20,
this.cornerCircular = 10,
this.color = Colors.white,
this.cornerRaido = 10,
this.threadStroke = ThreadStrokeType.round});
final double frameWidth;
final double frameHight;
final List<Widget> childs;
final double threadWidth;
final double frameLength;
final double cornerDistance;
final double cornerCircular;
final double cornerRaido;
final Color color;
final ThreadStrokeType threadStroke;
Widget build(BuildContext context) {
return SizedBox(
width: frameWidth,
height: frameHight,
child: Stack(
children: [
...childs,
Positioned(
child: SizedBox(
width: frameWidth,
height: frameHight,
child: CustomPaint(
size: Size(0.5.sw, 0.5.sh),
foregroundPainter: FourCorner(threadWidth, frameLength, color,
cornerDistance, cornerRaido, threadStroke),
),
))
],
),
);
}
}
class FourCorner extends CustomPainter {
final double threadWidth;
final Color color;
final double frameLength;
final double distance;
final double cornerRaido;
final ThreadStrokeType threadStrokeType;
FourCorner(this.threadWidth, this.frameLength, this.color, this.distance,
this.cornerRaido, this.threadStrokeType);
void paint(Canvas canvas, Size size) {
Paint thread = Paint()
..strokeWidth = threadWidth
..color = color
..strokeCap = threadStrokeType == ThreadStrokeType.square
? StrokeCap.square
: (threadStrokeType == ThreadStrokeType.butt
? StrokeCap.butt
: StrokeCap.round)
..strokeJoin = threadStrokeType == ThreadStrokeType.square
? StrokeJoin.miter
: StrokeJoin.round
..style = PaintingStyle.stroke;
Paint completeArc = Paint()
..strokeWidth = threadWidth
..color = color
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
const double pi = 3.141592653589793;
/**
* topLeft
* C: center V:vertical H:horizontal
* S:Start E: end
*/
Offset topLeftPointC =
Offset(distance + cornerRaido, distance + cornerRaido);
Offset topLeftPointVS = Offset(distance, distance + cornerRaido);
Offset topLeftPointVE =
Offset(distance, distance + cornerRaido + frameLength);
Offset topLeftPointHS = Offset(distance + cornerRaido, distance);
Offset topLeftPointHE =
Offset(distance + cornerRaido + frameLength, distance);
/// topLeft vertical
canvas.drawLine(topLeftPointVS, topLeftPointVE, thread);
// topLeft corner
canvas.drawArc(Rect.fromCircle(center: topLeftPointC, radius: cornerRaido),
pi, pi / 2, false, completeArc);
/// topLeft horizontal
canvas.drawLine(topLeftPointHS, topLeftPointHE, thread);
/**
* topRight
* C: center V:vertical H:horizontal
* S:Start E: end
*/
Offset topRightPointC =
Offset(size.width - distance - cornerRaido, distance + cornerRaido);
Offset topRightPointVS =
Offset(size.width - distance, distance + cornerRaido);
Offset topRightPointVE =
Offset(size.width - distance, distance + frameLength);
Offset topRightPointHS =
Offset(size.width - distance - cornerRaido - frameLength, distance);
Offset topRightPointHE =
Offset(size.width - distance - cornerRaido, distance);
/// topRight Vertical
canvas.drawLine(topRightPointVS, topRightPointVE, thread);
/// topRight corner
canvas.drawArc(Rect.fromCircle(center: topRightPointC, radius: cornerRaido),
0, -pi / 2, false, completeArc);
/// topRight horizontal
canvas.drawLine(topRightPointHS, topRightPointHE, thread);
/**
* bottomLeft
* C: center V:vertical H:horizontal
* S:Start E: end
*/
Offset bottomLeftC =
Offset(distance + cornerRaido, size.height - distance - cornerRaido);
Offset bottomLeftVS =
Offset(distance, size.height - distance - cornerRaido);
Offset bottomLeftVE =
Offset(distance, size.height - distance -frameLength);
Offset bottomLeftHS =
Offset(distance + cornerRaido, size.height - distance);
Offset bottomLEftHE =
Offset(distance +cornerRaido+ frameLength, size.height - distance);
/// bottomLeft Vertical
canvas.drawLine(bottomLeftVS, bottomLeftVE, thread);
/// bottomLeft Corner
canvas.drawArc(Rect.fromCircle(center: bottomLeftC, radius: cornerRaido),
pi / 2, pi / 2, false, completeArc);
/// bottomLeft Horizontal
canvas.drawLine(bottomLeftHS, bottomLEftHE, thread);
/**
* bottomRight
* C: center V:vertical H:horizontal
* S:Start E: end
*/
Offset bottomRightC = Offset(size.width - distance - cornerRaido,
size.height - distance - cornerRaido);
Offset bottomRightVS = Offset(size.width - distance,
size.height - distance - cornerRaido - frameLength);
Offset bottomRightVE =
Offset(size.width - distance, size.height - distance - cornerRaido);
Offset bottomRightHS =
Offset(size.width - distance - cornerRaido, size.height - distance);
Offset bottomRightHE = Offset(
size.width - distance - frameLength - cornerRaido,
size.height - distance);
/// BottomRight Vertical
canvas.drawLine(bottomRightVS, bottomRightVE, thread);
/// BottomRight Corner
canvas.drawArc(Rect.fromCircle(center: bottomRightC, radius: cornerRaido),
0, pi / 2, false, completeArc);
/// BottomRight Horizontal
canvas.drawLine(bottomRightHS, bottomRightHE, thread);
}
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
效果图