颤动 - 在卡片上用文字绘制右上角的三角形

use*_*595 8 flutter

我想用文字绘制一个三角形,在卡片上具有右上角的绝对位置

例如:

在此处输入图片说明

我几乎实现了这一点,但是 1. 我想知道是否有一个简单的方法 2. 文本没有完全居中...

这是我的代码:(我为三角形使用油漆并为文本旋转)

class ShapesPainter extends CustomPainter {
  final Color color;

  ShapesPainter(this.color);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();

    paint.color = color;
    // create a path
    var path = Path();
   path.moveTo(size.width, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(size.width - size.height, 0);
    // close the path to form a bounded shape
    path.close();
    canvas.drawPath(path, paint);




  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

class EventStatusIndicator  extends StatelessWidget{
  final E.EventStatus eventStatus;

EventStatusIndicator(this.eventStatus);

  Widget build(ct) {
   return     Stack(
        children: <Widget>[
          CustomPaint(
            painter: ShapesPainter(eventStatusMap[this.eventStatus].color),
            child: Container(
              height: 100,
            ),
          ),
          Align (alignment: Alignment.topRight, child:  Container(
          margin: EdgeInsets.fromLTRB(0, 30, 0, 0),
          height: 60.0,
          width: 90,
          child:  Transform.rotate(angle:  math.pi / 4, child: 
          Text(eventStatusMap[this.eventStatus].display,  textAlign: TextAlign.center, style: TextStyle(color: eventStatusIndicatorColor, fontSize: 17)))

        ))

        ],
      );


  }
}
Run Code Online (Sandbox Code Playgroud)

我的结果: 在此处输入图片说明

小智 14

作为一个选项,最小的可重现代码

import 'dart:math' as math;
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text('I\'m awesome')),
        body: Column(
          children: <Widget>[
            Card(
              child: Container(
                width: 300,
                height: 200,
                padding: const EdgeInsets.all(16),
                child: Text('Lorem Ipsum is simply dummy text of the printing and typesetting industry.'),
                foregroundDecoration: const BadgeDecoration(
                  badgeColor: Colors.green,
                  badgeSize: 70,
                  textSpan: TextSpan(
                    text: 'AWESOME',
                    style: TextStyle(color: Colors.white, fontSize: 12),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class BadgeDecoration extends Decoration {
  final Color badgeColor;
  final double badgeSize;
  final TextSpan textSpan;

  const BadgeDecoration({@required this.badgeColor, @required this.badgeSize, @required this.textSpan});

  @override
  BoxPainter createBoxPainter([onChanged]) => _BadgePainter(badgeColor, badgeSize, textSpan);
}

class _BadgePainter extends BoxPainter {
  static const double BASELINE_SHIFT = 1;
  static const double CORNER_RADIUS = 4;
  final Color badgeColor;
  final double badgeSize;
  final TextSpan textSpan;

  _BadgePainter(this.badgeColor, this.badgeSize, this.textSpan);

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    canvas.save();
    canvas.translate(offset.dx + configuration.size.width - badgeSize, offset.dy);
    canvas.drawPath(buildBadgePath(), getBadgePaint());
    // draw text
    final hyp = math.sqrt(badgeSize * badgeSize + badgeSize * badgeSize);
    final textPainter = TextPainter(text: textSpan, textDirection: TextDirection.ltr, textAlign: TextAlign.center);
    textPainter.layout(minWidth: hyp, maxWidth: hyp);
    final halfHeight = textPainter.size.height / 2;
    final v = math.sqrt(halfHeight * halfHeight + halfHeight * halfHeight) + BASELINE_SHIFT;
    canvas.translate(v, -v);
    canvas.rotate(0.785398); // 45 degrees
    textPainter.paint(canvas, Offset.zero);
    canvas.restore();
  }

  Paint getBadgePaint() => Paint()
    ..isAntiAlias = true
    ..color = badgeColor;

  Path buildBadgePath() => Path.combine(
      PathOperation.difference,
      Path()..addRRect(RRect.fromLTRBAndCorners(0, 0, badgeSize, badgeSize, topRight: Radius.circular(CORNER_RADIUS))),
      Path()
        ..lineTo(0, badgeSize)
        ..lineTo(badgeSize, badgeSize)
        ..close());
}
Run Code Online (Sandbox Code Playgroud)

结果
在此处输入图片说明

您可以根据需要定义徽章大小和颜色、任何文本和样式。