import 'package:flutter/material.dart'; import 'package:remixicon/remixicon.dart'; class AvatarCard extends StatefulWidget { const AvatarCard({super.key}); @override State createState() => _AvatarCardState(); } class _AvatarCardState extends State with SingleTickerProviderStateMixin { bool _isShow = false; late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: Duration(milliseconds: 400), ); } void _toggleShow() { setState(() { _isShow = !_isShow; if (_isShow) { _controller.forward(); } else { _controller.reverse(); } }); } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: Transform.translate( offset: Offset(0, 50), child: Column( children: [ Transform( alignment: Alignment.center, transform: Matrix4.identity()..translate(40.0, 40.0)..scale(0.2), child: Container( color: Colors.red, padding: EdgeInsets.only(bottom: 10), child: InkWell( onTap: _toggleShow, child: Stack( children: [ Container( padding: EdgeInsets.all(4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(3), border: Border.all(color: Colors.black, width: 1), ), child: Text( "好的,让我们把学习软件开发这个目标分解成最简单的小步骤,这样你明天就能轻松开始行动", style: TextStyle(fontSize: 12), ), ), Positioned( bottom: 0, left: 0, right: 0, child: CustomPaint( painter: BubblePainter(), ), ), ], ), ), ), ), SizedBox( width: double.infinity, child: Stack( alignment: Alignment.bottomCenter, children: [ Image.asset("assets/image/xiaozhi.png", height: 100), Positioned( top: 20, child: Transform.translate( offset: Offset(50, -10), child: GestureDetector( onTap: _toggleShow, child: Icon(RemixIcons.message_2_line, size: 26), ), ), ), ], ), ), ], ), ), ); } } class BubblePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { var bottomWidth = 10; //点坐标 var start = Offset((size.width - bottomWidth) / 2, 0); //底线 final bottomLinePaint = Paint() ..color = Colors.white ..strokeWidth = 2 ..style = PaintingStyle.stroke; final bottomLinePath = Path() ..moveTo(start.dx, 0) ..lineTo(start.dx + bottomWidth, 0); canvas.drawPath(bottomLinePath, bottomLinePaint); //边线 final sideLinePaint = Paint() ..color = Colors.black ..strokeWidth = 1 ..style = bottomLinePaint.style; final sideLinePath = Path() ..moveTo(start.dx, 0) ..lineTo(start.dx + bottomWidth / 2, 5) ..lineTo(start.dx + bottomWidth, 0); canvas.drawPath(sideLinePath, sideLinePaint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } }