当前位置:   article > 正文

Flutter 自定义Widget 圆角矩形加三角指示器_flutter 圆角三角形

flutter 圆角三角形

一般app设计中都会有气泡提示,这个时候就需要用到切图了,在flutter中不管你信不信 反正对于.9的这块还是很不友好的,使用起来特别麻烦。要是安卓中这或许会很简单。
但即使支持.9 如果气泡样式很多,对于app的包大小占用其实还是有那么一丢丢的影响的。
我采用了是用代码的方式实现了圆角矩形带三角指示器
现看看效果吧
在这里插入图片描述

在这里插入图片描述
上面就是ui给出的效果,其中底部的三角形距离左边的位置还是动态可变,背景颜色还是渐变的。
使用了CustomPaint方式实现一套圆角矩形加指示器的控件,下面是代码实现

ExRoundTriangleWidget

import 'dart:math';

import 'package:flutter/material.dart';

import 'ex_text.dart';

/// 圆角矩形 + 三角提示布局
class ExRoundTriangleWidget extends StatelessWidget {
  /// 子布局
  final String data; // 文案
  final TextStyle textStyle;
  final double roundRadius; // 圆角半径
  final double triangleWidth; // 三角形的宽度
  final double triangleHeight; // 三角形的高度
  final double triangleDistance; // 三角形距离左边的距离
  final bool triangleFromLeft; // 从左边计算距离
  final LinearGradient gradient; // 渐变颜色
  final Color bordColor; // 边框颜色
  final PaintingStyle paintingStyle; // 是填充还是边框
  final double strokeWidth; // 画笔宽度
  final bool isCenter; // 是否居中
  final double horizontal; // 水平间距

  ExRoundTriangleWidget(
      {this.data,
        this.textStyle,
        this.roundRadius,
        this.triangleWidth,
        this.triangleHeight,
        this.triangleDistance,
        this.triangleFromLeft,
        this.gradient,
        this.bordColor,
        this.paintingStyle,
        this.strokeWidth,
        this.isCenter,
        this.horizontal});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: ExRoundTrianglePainter(
        roundRadius: roundRadius ?? 12,
        triangleWidth: triangleWidth ?? 12,
        triangleHeight: triangleHeight ?? 12,
        triangleDistance: triangleDistance ?? 8,
        triangleFromLeft: triangleFromLeft ?? true,
        gradient: gradient,
        bordColor: bordColor,
        paintingStyle: paintingStyle,
        strokeWidth: strokeWidth,
        isCenter: isCenter,
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            height: (roundRadius ?? 12) * 2 + (triangleHeight ?? 12),
            alignment: Alignment.center,
            child: Container(
              padding: EdgeInsets.symmetric(horizontal: horizontal),
              height: (roundRadius ?? 12) * 2,
              alignment: Alignment.center,
              child: ExText(
                data,
                textStyle,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

/// 圆角矩形 带有三角指示器
class ExRoundTrianglePainter extends CustomPainter {
  Paint _paint;
  final double roundRadius; // 圆角半径
  final double triangleWidth; // 三角形的宽度
  final double triangleHeight; // 三角形的高度
  final double triangleDistance; // 三角形距离左边的距离
  final bool triangleFromLeft; // 从左边计算距离
  LinearGradient gradient; // 渐变颜色
  final Color bordColor; // 边框颜色
  final PaintingStyle paintingStyle; // 是填充还是边框
  final double strokeWidth; // 画笔宽度
  final bool isCenter; // 是否居中
  final double horizontal; // 水平间距

  ExRoundTrianglePainter(
      {this.roundRadius = 12,
        this.triangleWidth = 12,
        this.triangleHeight = 12,
        this.triangleDistance = 16,
        this.triangleFromLeft = true,
        this.gradient,
        this.bordColor,
        this.paintingStyle = PaintingStyle.fill,
        this.strokeWidth = 1,
        this.isCenter = false,
        this.horizontal = 12}) {
    _paint = Paint()
      ..strokeCap = StrokeCap.butt
      ..isAntiAlias = true //是否启动抗锯齿
      ..style = paintingStyle ?? PaintingStyle.fill //绘画风格,默认为填充
      ..filterQuality = FilterQuality.high //颜色渲染模式的质量
      ..strokeWidth = strokeWidth ?? 15.0 //画笔的宽度
      ..color = bordColor ?? Colors.transparent; // 边框颜色
  }

  @override
  void paint(Canvas canvas, Size size) {
    final rect = new Rect.fromLTWH(0.0, 0.0, size.width, size.height);
    if (gradient != null) {
      _paint.shader = gradient.createShader(rect);
    }

    Path path = Path();
    // 左半圆
    path.addArc(new Rect.fromLTWH(0, 0, roundRadius * 2, roundRadius * 2), 90.0 * (pi / 180.0), 180.0 * (pi / 180.0));
    path.lineTo(size.width - roundRadius, 0);
    // 右半圆
    path.addArc(new Rect.fromLTWH(size.width - roundRadius * 2, 0, roundRadius * 2, roundRadius * 2),
        270.0 * (pi / 180.0), 180.0 * (pi / 180.0));

    double reallyTriangleStartDistance; // 三角形的x轴的起始距离 根据triangleFromLeft计算 从右到左开始的
    double reallyTriangleCenterDistance; // 三角形的x轴的中见点距离 根据triangleFromLeft计算 从右到左开始的
    double reallyTriangleEndDistance; // 三角形的x轴的结束距离 根据triangleFromLeft计算 从右到左开始的
    if (isCenter ?? false) {
      reallyTriangleStartDistance = size.width / 2 - triangleWidth / 2;
      reallyTriangleCenterDistance = size.width / 2;
      reallyTriangleEndDistance = size.width / 2 + triangleWidth / 2;
    } else {
      if (triangleFromLeft) {
        reallyTriangleStartDistance = roundRadius + triangleDistance + triangleWidth;
        reallyTriangleCenterDistance = reallyTriangleStartDistance - triangleWidth / 2;
        reallyTriangleEndDistance = reallyTriangleCenterDistance - triangleWidth / 2;
      } else {
        reallyTriangleStartDistance = size.width - roundRadius - triangleDistance;
        reallyTriangleCenterDistance = reallyTriangleStartDistance - triangleWidth / 2;
        reallyTriangleEndDistance = reallyTriangleCenterDistance - triangleWidth / 2;
      }
    }

    // 三角形
    path.lineTo(reallyTriangleEndDistance, roundRadius * 2);
    path.lineTo(reallyTriangleCenterDistance, roundRadius * 2 + triangleHeight);
    path.lineTo(reallyTriangleStartDistance, roundRadius * 2);

    path.lineTo(roundRadius, roundRadius * 2);

    canvas.drawPath(path, _paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号