【问题标题】:flutter - paint a top-right triangle with a text on a card颤动 - 用卡片上的文字绘制右上角的三角形
【发布时间】:2019-08-17 18:33:27
【问题描述】:

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

例如:

我几乎做到了,但是 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)))

        ))

        ],
      );


  }
}

我的结果:

【问题讨论】:

    标签: flutter


    【解决方案1】:

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

    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());
    }
    

    结果

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

    【讨论】:

    猜你喜欢
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多