dart Flutter如何创建顶部带有箭头的盒子容器?

oaxa6hgo  于 2023-07-31  发布在  Flutter
关注(0)|答案(3)|浏览(170)

嗨,我如何创建一个顶部带有箭头的盒子容器,而不使用任何pub包。
就像下面。


的数据

zzzyeukh

zzzyeukh1#

您可以自定义类似于此post的ShapeBorder。然后,不要使用rect.bottomCenter作为Path(),而是将其更改为rect.TopCenter以将绘制的Rect放置在顶部。

Path()dart
  ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2)))
  ..moveTo(rect.topCenter.dx - 10, rect.topCenter.dy)
  ..relativeLineTo(10, 20)
  ..relativeLineTo(20, -20)
  ..close();

字符串

b1uwtaje

b1uwtaje2#

添加此小部件管理isShow status,

Stack(
                  alignment: Alignment.centerRight,
                  children: [
                    Align(
                      alignment: Alignment.centerLeft,
                      child: Visibility(
                        visible: isShow,
                        child: const TestScreens(),
                      ),
                    ),
                    const Center(
                      child: Text(
                        'Domestic Fixed Deposits plus',
                        style: TextStyle(
                            fontSize: 20,
                            color: Colors.black,
                            letterSpacing: 3,
                            fontWeight: FontWeight.bold),
                      ),
                    ),
                  ],
                ),

字符串

顶部带有三角形箭头的自定义盒子容器

import 'package:flutter/material.dart';

class TestScreens extends StatefulWidget {
  const TestScreens({super.key});

  @override
  State<TestScreens> createState() => _TestScreensState();
}

class _TestScreensState extends State<TestScreens>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Center(
            child: CustomPaint(
              painter: TrianglePainter(
                strokeColor: Colors.blue,
                strokeWidth: 0,
                paintingStyle: PaintingStyle.fill,
              ),
              child: const SizedBox(
                height: 15,
                width: 25,
              ),
            ),
          ),
          Container(
            color: Colors.blue,
            width: 150.0,
            height: 100.0,
            child: const Center(
              child: Text('Rectangle'),
            ),
          ),
        ],
      ),
    );
  }
}

class TrianglePainter extends CustomPainter {
  final Color strokeColor;
  final PaintingStyle paintingStyle;
  final double strokeWidth;

  TrianglePainter(
      {this.strokeColor = Colors.black,
      this.strokeWidth = 3,
      this.paintingStyle = PaintingStyle.stroke});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = strokeColor
      ..strokeWidth = strokeWidth
      ..style = paintingStyle;

    canvas.drawPath(getTrianglePath(size.width, size.height), paint);
  }

  Path getTrianglePath(double x, double y) {
    return Path()
      ..moveTo(0, y)
      ..lineTo(x / 2, 0)
      ..lineTo(x, y)
      ..lineTo(0, y);
  }

  @override
  bool shouldRepaint(TrianglePainter oldDelegate) {
    return oldDelegate.strokeColor != strokeColor ||
        oldDelegate.paintingStyle != paintingStyle ||
        oldDelegate.strokeWidth != strokeWidth;
  }
}


的数据

kx1ctssn

kx1ctssn3#

对于我的例子,我为flutter工具提示定制了一个shapeborder。

class TooltipShippingFeeBorder extends ShapeBorder{

  @override
  EdgeInsetsGeometry get dimensions => const EdgeInsets.only(top:20);

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    return  Path()
      ..fillType = PathFillType.evenOdd
      ..addPath(getOuterPath(rect), Offset.zero);
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    rect = Rect.fromPoints(rect.topLeft, rect.bottomRight - Offset(0, 20));
    return Path()
      ..addRRect(RRect.fromRectAndRadius(rect, const Radius.circular(6)))
      ..moveTo(rect.topCenter.dx - 10, rect.topCenter.dy)
      ..relativeLineTo(10, -20)
      ..relativeLineTo(20, 20)
      ..close();
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {

  }

  @override
  ShapeBorder scale(double t) => this;

}

字符串
并在工具提示中使用它,如下所示:

Tooltip(
          triggerMode: TooltipTriggerMode.tap,
          padding: const EdgeInsets.only(bottom: 16, left: 10, right: 10),
          decoration: ShapeDecoration(
              shape: TooltipShippingFeeBorder(),
              color: WalletTheme.primaryColor),
          message: '$shippingFeeMessage\n',
          child: const Icon(
            Icons.info_outline,
            size: 16,
            color: WalletTheme.grey2,
          ),
        )


因此,在您的示例中,您还创建了相同的边框,并对Container使用ShapreDecoration。

ShapeDecoration(
                  shape: TooltipShippingFeeBorder(),
                  color: WalletTheme.primaryColor)

相关问题