如何在flutter中实现聊天气泡形状的小部件

w6mmgewl  于 2023-01-09  发布在  Flutter
关注(0)|答案(4)|浏览(363)

我想设计一个聊天泡泡形状的小部件,其中一个角被固定,它的高度应该调整为文本的行?现在我使用的是带有一些borderRadius的ClipRRect小部件。但我想固定一个角。有什么建议吗?

    • 更新**

我知道这可以通过使用堆栈来实现,但我正在寻找一个更好的解决方案,因为我必须在一个视图中多次使用它,并且使用多个堆栈可能会影响性能。(如果我错了,请纠正我)

imzjd6km

imzjd6km1#

对于想要这样做的人,请使用库。您可以从www.example.com添加bubble: ^1.1.9+1(获取最新)包pub.dev,并使用气泡 Package 您的消息。

Bubble(
style: right ? styleMe : styleSomebody,
//Your message content child here...
)

这里right是布尔值,它告诉你气泡是在左边还是右边,写你的逻辑,并添加样式属性styleMestyleSomebody到你的小部件中,如下所示。根据你的主题改变样式。

double pixelRatio = MediaQuery.of(context).devicePixelRatio;
double px = 1 / pixelRatio;

 BubbleStyle styleSomebody = BubbleStyle(
      nip: BubbleNip.leftTop,
      color: Colors.white,
      elevation: 1 * px,
      margin: BubbleEdges.only(top: 8.0, right: 50.0),
      alignment: Alignment.topLeft,
    );

    BubbleStyle styleMe = BubbleStyle(
      nip: BubbleNip.rightTop,
      color: Colors.grey,
      elevation: 1 * px,
      margin: BubbleEdges.only(top: 8.0, left: 50.0),
      alignment: Alignment.topRight,
    );
wbrvyc0a

wbrvyc0a2#

嗨,我也在寻找一个聊天泡泡形状的小工具,最后我做了一个。我已经在自定义画家这一点,我不擅长。

import 'package:flutter/material.dart';

class ChatBubble extends CustomPainter {
  final Color color;
  final Alignment alignment;

  ChatBubble({
    @required this.color,
    this.alignment,
  });

  var _radius = 10.0;
  var _x = 10.0;



  @override
  void paint(Canvas canvas, Size size) {
    if (alignment == Alignment.topRight) {
      canvas.drawRRect(
          RRect.fromLTRBAndCorners(
            0,
            0,
            size.width - 8,
            size.height,
            bottomLeft: Radius.circular(_radius),
            topRight: Radius.circular(_radius),
            topLeft: Radius.circular(_radius),
          ),
          Paint()
            ..color = this.color
            ..style = PaintingStyle.fill);
      var path = new Path();
      path.moveTo(size.width - _x, size.height - 20);
      path.lineTo(size.width - _x, size.height);
      path.lineTo(size.width, size.height);
      canvas.clipPath(path);
      canvas.drawRRect(
          RRect.fromLTRBAndCorners(
            size.width - _x,
            0.0,
            size.width,
            size.height,
            topRight: Radius.circular(_radius),
          ),
          Paint()
            ..color = this.color
            ..style = PaintingStyle.fill);
    } else {
      canvas.drawRRect(
          RRect.fromLTRBAndCorners(
            _x,
            0,
            size.width,
            size.height,
            bottomRight: Radius.circular(_radius),
            topRight: Radius.circular(_radius),
            topLeft: Radius.circular(_radius),
          ),
          Paint()
            ..color = this.color
            ..style = PaintingStyle.fill);
      var path = new Path();
      path.moveTo(0, size.height);
      path.lineTo(_x, size.height);
      path.lineTo(_x, size.height-20);
      canvas.clipPath(path);
      canvas.drawRRect(
          RRect.fromLTRBAndCorners(
            0,
            0.0,
            _x,
            size.height,
            topRight: Radius.circular(_radius),
          ),
          Paint()
            ..color = this.color
            ..style = PaintingStyle.fill);
    }
  }

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

复制并粘贴以上代码并粘贴到你的项目中

Align(
      alignment: alignment, //Change this to Alignment.topRight or Alignment.topLeft
      child: CustomPaint(
        painter: ChatBubble(color: Colors.blue, alignment: alignment),
        child: Container(
          margin: EdgeInsets.all(10),
          child: Stack(
            children: <Widget>[
              TextView("Hello World"),
            ],
          ),
        ),
      ),
    )

粘贴此代码的地方,你必须显示聊天泡泡小工具。我也上传此代码在bitbucket ChatBubble Widget请免费,如果你有任何贡献。

lsmd5eda

lsmd5eda3#

对不起,我不能给你看它的代码,但我可以提出一个想法,如果你正确地实现它可能会工作。假设你用ClipRect做的小部件被称为MyChatBubbleRect。现在,用CustomPainter做另一个小部件,画一个三角形,让我们称之为MyChatBubbleTriangle。当然,我用聊天气泡的颜色填充它,但是你可以在调试时使用不同的颜色。现在我们有了两个可以堆叠的小部件em放在一起,并使用Positioned小部件覆盖MyChatBubbleTriangle。类似于以下内容:

Stack(
  children : [
     MyChatBubbleRect(), // Maybe decrease the width a bit
     Positioned(
        top: 0,
        right: 0,
        child: MyChatBubbleTriangle()
     )
  ]
)

这只是一个想法,我认为你可以追求。抱歉不能提供适当的源代码。

xtfmy6hx

xtfmy6hx4#

聊天正文

DecoratedBox(
    decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8.0),
   ),
   child: Text("your message goes here"),
);

创建自定义三角形

class ChatBubbleTriangle extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()..color = Colors.blue;

    var path = Path();
    path.lineTo(-10, 0);
    path.lineTo(0, 10);
    path.lineTo(10, 0);
    canvas.drawPath(path, paint);
  }

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

在一个包含ChatBubbleTrianglePositioned()小部件的堆栈中使用它们

相关问题