【问题标题】:Flutter design Instagram like balloons / tooltip widgetFlutter 设计 Instagram 之类的气球/工具提示小部件
【发布时间】:2020-02-09 15:57:11
【问题描述】:

在颤振中我想将此布局设计为小部件

当前实现的代码有这样的结果:

你能帮我解决这个设计的一些问题吗?

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

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

【问题讨论】:

  • @kherel 你能帮我写这篇文章吗?谢谢
  • stackoverflow.com/a/57943257/2252830 ,它会像这样制作气球:i.stack.imgur.com/DDXMA.png - 但如何定制它取决于你
  • 那么你看到上面的答案了吗?您是否看到如何以简单的方式做到这一点并使其“可点击”?使用以下答案的复杂代码的原因是什么?
  • @pskink 下面的答案并不像我想的那样复杂,而且在更少的代码中易于使用
  • 是的,这是一种解决方法,因为作者无法制作气球状形状并通过使用标准装饰和自定义油漆将其组合 - 而应该通过定义自定义来完成形状 (ShapeBorder) 或通过定义自定义剪辑 (CustomClipper) - 如果你想使用这样的解决方法,它取决于你......

标签: flutter flutter-layout


【解决方案1】:

编辑:正如 pskink 在这个问题中提到的:Flutter - ClipPath,这将是实现您想要的正确方法:

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它不会有任何曲率,如果你设置它为@ 987654331@它将具有最大曲率。

要了解quadraticBezierTo 的工作原理以及如何制作其他形状,请查看此链接:Paths in Flutter: A Visual Guide

【讨论】:

  • 谢谢,那么三角角呢?如何为它们设置半径?
  • 请参阅stackoverflow.com/a/57943257/2252830,了解如何创建像“消息气球”这样的自定义形状 - 这是通过扩展 ShapeBorder 类来完成的
  • 这是来自ShapeBorder官方文档:“子类定义了各种形状,比如圆形(CircleBorder)、圆角矩形(RoundedRectangleBorder)、连续矩形(ContinuousRectangleBorder)或斜角矩形(BeveledRectangleBorder) 。”
  • 顺便说一句,您也可以将您的TooltipShapeBorder 用作“可点击的气球” - 请参阅我发布的链接中的ButtonMessage 小部件 - 它在内部使用MaterialInkWell 小部件
  • 如何将箭头向左移动?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多