123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import 'package:flutter/material.dart';
- const double _width = 170;
- const double _height = 38;
- class TitleClipRect extends StatelessWidget {
- const TitleClipRect({
- super.key,
- this.color = Colors.grey,
- required this.title,
- required this.arrowHeight,
- required this.clickTitle,
- });
- final Color? color;
- final String title;
- final double arrowHeight;
- final Function clickTitle;
- @override
- Widget build(BuildContext context) {
- return InkWell(
- onTap: () {
- clickTitle.call();
- },
- customBorder: HoleShapeBorder(arrowHeight),
- child: Card(
- margin: const EdgeInsets.all(0),
- shape: HoleShapeBorder(arrowHeight),
- color: color,
- elevation: color == null ? 5 : 0,
- shadowColor: Theme.of(context).primaryColor.withOpacity(0.8),
- child: ClipPath(
- clipper: TitleClipPath(arrowHeight),
- child: Container(
- width: _width,
- height: _height,
- padding: const EdgeInsets.symmetric(
- horizontal: 15,
- ),
- decoration: BoxDecoration(
- boxShadow: [
- BoxShadow(
- color: Theme.of(context).primaryColor.withOpacity(1),
- ),
- ],
- color: color,
- ),
- alignment: Alignment.center,
- child: FittedBox(
- child: Text(
- title,
- style: const TextStyle(color: Colors.white, fontSize: 20),
- ),
- ),
- ),
- ),
- ),
- );
- }
- }
- class TitleClipPath extends CustomClipper<Path> {
- final double arrowHeight;
- TitleClipPath(this.arrowHeight);
- @override
- Path getClip(Size size) {
- final height = size.height;
- final arrowBase = height / 2;
- // final arrowPLine = math.tan(120 / 180) * arrowBase;
- final path = Path();
- path.moveTo(0, 0); // 左上角
- path.lineTo(size.width - arrowHeight, 0); // 右上角
- path.lineTo(size.width, arrowBase); // 右端点
- path.lineTo(size.width - arrowHeight, height); // 右下角
- path.lineTo(0, height); // 左下角
- path.lineTo(arrowHeight, arrowBase); // 左端点
- path.lineTo(0, 0); // 左上角
- return path;
- }
- @override
- bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
- return false;
- }
- }
- class HoleShapeBorder extends ShapeBorder {
- final Offset offset;
- final double size;
- final double arrowHeight;
- const HoleShapeBorder(this.arrowHeight,
- {this.offset = const Offset(0, 0), this.size = 0});
- @override
- EdgeInsetsGeometry get dimensions => throw UnimplementedError();
- @override
- void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}
- @override
- Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
- var path = Path();
- final height = rect.size.height;
- final arrowBase = height / 2;
- path.moveTo(0, 0); // 左上角
- path.lineTo(rect.size.width - arrowHeight, 0); // 右上角
- path.lineTo(rect.size.width, arrowBase); // 右端点
- path.lineTo(rect.size.width - arrowHeight, height); // 右下角
- path.lineTo(0, height); // 左下角
- path.lineTo(arrowHeight, arrowBase); // 左端点
- path.lineTo(0, 0); // 左上角
- return path;
- }
- @override
- ShapeBorder scale(double t) {
- // TODO: implement scale
- throw UnimplementedError();
- }
- @override
- Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
- // TODO: implement getInnerPath
- throw UnimplementedError();
- }
- }
|