像气球/工具提示小部件一样的Flutter设计Instagram [英] Flutter design Instagram like balloons / tooltip widget

查看:103
本文介绍了像气球/工具提示小部件一样的Flutter设计Instagram的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在扑朔迷离中,我想将此布局设计为小部件

in flutter i would like to design this layout as widget

并且当前实现的代码具有以下结果:

and current implemented code has this result:

您能帮我解决此问题吗?

could you help me to fix some problem on this desing?

因为高度/重量和拐角应该可自定义,我应该在其中放入一些小部件,例如:

in that height/weight and corners should be customizable and i should can put some widget into that, for example:

class MessageClipper extends CustomClipper<Path> {
  MessageClipper({this.borderRadius = 15});
  final double borderRadius;
  @override
  Path getClip(Size size) {
    double width = size.width;
    double height = size.height;
    double rheight = height - height / 3;
    double oneThird = width / 3;

    final path = Path()
      ..lineTo(0, rheight - borderRadius)
      ..cubicTo(0, rheight - borderRadius, 0, rheight, borderRadius, rheight)
      ..lineTo(oneThird, rheight)
      ..lineTo(width/2-borderRadius, height-borderRadius)
      ..cubicTo(width / 2 - borderRadius, height - borderRadius, width / 2,
          height, width / 2 + borderRadius, height - borderRadius )
      ..lineTo(2 * oneThird, rheight)
      ..lineTo(width-borderRadius, rheight)
      ..cubicTo(width - borderRadius, rheight, width, rheight, width,
          rheight - borderRadius)
      ..lineTo(width, 0)
      ..lineTo(0, 0);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}

推荐答案

编辑:正如以下问题中提到的pskink:

As pskink metioned in this question: Flutter - ClipPath, this would be the correct way to achieve what you want:

class TooltipShapeBorder extends ShapeBorder {
  final double arrowWidth;
  final double arrowHeight;
  final double arrowArc;
  final double radius;

  TooltipShapeBorder({
    this.radius = 16.0,
    this.arrowWidth = 20.0,
    this.arrowHeight = 10.0,
    this.arrowArc = 0.0,
  }) : assert(arrowArc <= 1.0 && arrowArc >= 0.0);

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: arrowHeight);

  @override
  Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;

  @override
  Path getOuterPath(Rect rect, {TextDirection textDirection}) {
    rect = Rect.fromPoints(rect.topLeft, rect.bottomRight - Offset(0, arrowHeight));
    double x = arrowWidth, y = arrowHeight, r = 1 - arrowArc;
    return Path()
      ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(radius)))
      ..moveTo(rect.bottomCenter.dx + x / 2, rect.bottomCenter.dy)
      ..relativeLineTo(-x / 2 * r, y * r)
      ..relativeQuadraticBezierTo(-x / 2 * (1 - r), y * (1 - r), -x * (1 - r), 0)
      ..relativeLineTo(-x / 2 * r, -y * r);
  }

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

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

这是使用方法:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Instagram Like Balloon Tooltip'),
    ),
    body: Center(
      child: Container(
        decoration: ShapeDecoration(
          color: Colors.red,
          shape: TooltipShapeBorder(arrowArc: 0.5),
          shadows: [
            BoxShadow(
                color: Colors.black26, blurRadius: 4.0, offset: Offset(2, 2))
          ],
        ),
        child: Padding(
          padding: EdgeInsets.all(16.0),
          child: Text('Text 22', style: TextStyle(color: Colors.white)),
        ),
      ),
    ),
  );
}

这将是结果:

如果要更改箭头的曲率,可以使用TooltipShapeBorderarrowArc属性,如果将其设置为0.0,则不会有任何曲率,并且如果将其设置为1.0将具有最大曲率.

If you want to change the curvature of the arrow, you can use the arrowArc propery of the TooltipShapeBorder, if you set it to 0.0 it won't have any curvature and if you set it to 1.0 it will have the maximum curvature.

要查看quadraticBezierTo的工作方式以及如何制作其他形状,请检查以下链接:

To see how quadraticBezierTo works and how to make other shapes check this link: Paths in Flutter: A Visual Guide

这篇关于像气球/工具提示小部件一样的Flutter设计Instagram的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆